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/Makefile4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c107
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c1034
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.h91
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c982
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c972
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h231
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h91
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c268
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h21
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c20
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h1
17 files changed, 2048 insertions, 1801 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 57cddee03252..1d2ceac3a221 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -24,6 +24,7 @@ ccflags-y += -D__CHECK_ENDIAN__
24obj-$(CONFIG_BRCMFMAC) += brcmfmac.o 24obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
25brcmfmac-objs += \ 25brcmfmac-objs += \
26 wl_cfg80211.o \ 26 wl_cfg80211.o \
27 chip.o \
27 fwil.o \ 28 fwil.o \
28 fweh.o \ 29 fweh.o \
29 fwsignal.o \ 30 fwsignal.o \
@@ -36,8 +37,7 @@ brcmfmac-objs += \
36 btcoex.o 37 btcoex.o
37brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ 38brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
38 dhd_sdio.o \ 39 dhd_sdio.o \
39 bcmsdh.o \ 40 bcmsdh.o
40 sdio_chip.o
41brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ 41brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
42 usb.o 42 usb.o
43brcmfmac-$(CONFIG_BRCMDBG) += \ 43brcmfmac-$(CONFIG_BRCMDBG) += \
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index fa35b23bbaa7..a16e644e7c08 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -43,7 +43,6 @@
43#include "dhd_bus.h" 43#include "dhd_bus.h"
44#include "dhd_dbg.h" 44#include "dhd_dbg.h"
45#include "sdio_host.h" 45#include "sdio_host.h"
46#include "sdio_chip.h"
47 46
48#define SDIOH_API_ACCESS_RETRY_LIMIT 2 47#define SDIOH_API_ACCESS_RETRY_LIMIT 2
49 48
@@ -54,6 +53,12 @@
54/* Maximum milliseconds to wait for F2 to come up */ 53/* Maximum milliseconds to wait for F2 to come up */
55#define SDIO_WAIT_F2RDY 3000 54#define SDIO_WAIT_F2RDY 3000
56 55
56#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
57#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
58
59static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
60module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
61MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
57 62
58static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id) 63static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
59{ 64{
@@ -264,26 +269,17 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
264 break; 269 break;
265 } 270 }
266 271
267 if (ret) { 272 if (ret)
268 /* 273 brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
269 * SleepCSR register access can fail when 274 write ? "write" : "read", fn, addr, ret);
270 * waking up the device so reduce this noise 275
271 * in the logs.
272 */
273 if (addr != SBSDIO_FUNC1_SLEEPCSR)
274 brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
275 write ? "write" : "read", fn, addr, ret);
276 else
277 brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
278 write ? "write" : "read", fn, addr, ret);
279 }
280 return ret; 276 return ret;
281} 277}
282 278
283static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 279static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
284 u8 regsz, void *data, bool write) 280 u8 regsz, void *data, bool write)
285{ 281{
286 u8 func_num; 282 u8 func;
287 s32 retry = 0; 283 s32 retry = 0;
288 int ret; 284 int ret;
289 285
@@ -297,9 +293,9 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
297 * The rest: function 1 silicon backplane core registers 293 * The rest: function 1 silicon backplane core registers
298 */ 294 */
299 if ((addr & ~REG_F0_REG_MASK) == 0) 295 if ((addr & ~REG_F0_REG_MASK) == 0)
300 func_num = SDIO_FUNC_0; 296 func = SDIO_FUNC_0;
301 else 297 else
302 func_num = SDIO_FUNC_1; 298 func = SDIO_FUNC_1;
303 299
304 do { 300 do {
305 if (!write) 301 if (!write)
@@ -307,16 +303,26 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
307 /* for retry wait for 1 ms till bus get settled down */ 303 /* for retry wait for 1 ms till bus get settled down */
308 if (retry) 304 if (retry)
309 usleep_range(1000, 2000); 305 usleep_range(1000, 2000);
310 ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, 306 ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
311 data, write); 307 data, write);
312 } while (ret != 0 && ret != -ENOMEDIUM && 308 } while (ret != 0 && ret != -ENOMEDIUM &&
313 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 309 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
314 310
315 if (ret == -ENOMEDIUM) 311 if (ret == -ENOMEDIUM)
316 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); 312 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
317 else if (ret != 0) 313 else if (ret != 0) {
318 brcmf_err("failed with %d\n", ret); 314 /*
319 315 * SleepCSR register access can fail when
316 * waking up the device so reduce this noise
317 * in the logs.
318 */
319 if (addr != SBSDIO_FUNC1_SLEEPCSR)
320 brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
321 write ? "write" : "read", func, addr, ret);
322 else
323 brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
324 write ? "write" : "read", func, addr, ret);
325 }
320 return ret; 326 return ret;
321} 327}
322 328
@@ -488,7 +494,6 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
488 struct mmc_request mmc_req; 494 struct mmc_request mmc_req;
489 struct mmc_command mmc_cmd; 495 struct mmc_command mmc_cmd;
490 struct mmc_data mmc_dat; 496 struct mmc_data mmc_dat;
491 struct sg_table st;
492 struct scatterlist *sgl; 497 struct scatterlist *sgl;
493 int ret = 0; 498 int ret = 0;
494 499
@@ -533,16 +538,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
533 pkt_offset = 0; 538 pkt_offset = 0;
534 pkt_next = target_list->next; 539 pkt_next = target_list->next;
535 540
536 if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
537 ret = -ENOMEM;
538 goto exit;
539 }
540
541 memset(&mmc_req, 0, sizeof(struct mmc_request)); 541 memset(&mmc_req, 0, sizeof(struct mmc_request));
542 memset(&mmc_cmd, 0, sizeof(struct mmc_command)); 542 memset(&mmc_cmd, 0, sizeof(struct mmc_command));
543 memset(&mmc_dat, 0, sizeof(struct mmc_data)); 543 memset(&mmc_dat, 0, sizeof(struct mmc_data));
544 544
545 mmc_dat.sg = st.sgl; 545 mmc_dat.sg = sdiodev->sgtable.sgl;
546 mmc_dat.blksz = func_blk_sz; 546 mmc_dat.blksz = func_blk_sz;
547 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; 547 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
548 mmc_cmd.opcode = SD_IO_RW_EXTENDED; 548 mmc_cmd.opcode = SD_IO_RW_EXTENDED;
@@ -558,7 +558,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
558 while (seg_sz) { 558 while (seg_sz) {
559 req_sz = 0; 559 req_sz = 0;
560 sg_cnt = 0; 560 sg_cnt = 0;
561 sgl = st.sgl; 561 sgl = sdiodev->sgtable.sgl;
562 /* prep sg table */ 562 /* prep sg table */
563 while (pkt_next != (struct sk_buff *)target_list) { 563 while (pkt_next != (struct sk_buff *)target_list) {
564 pkt_data = pkt_next->data + pkt_offset; 564 pkt_data = pkt_next->data + pkt_offset;
@@ -640,7 +640,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
640 } 640 }
641 641
642exit: 642exit:
643 sg_free_table(&st); 643 sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
644 while ((pkt_next = __skb_dequeue(&local_list)) != NULL) 644 while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
645 brcmu_pkt_buf_free_skb(pkt_next); 645 brcmu_pkt_buf_free_skb(pkt_next);
646 646
@@ -827,7 +827,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
827 } 827 }
828 if (!write) 828 if (!write)
829 memcpy(data, pkt->data, dsize); 829 memcpy(data, pkt->data, dsize);
830 skb_trim(pkt, dsize); 830 skb_trim(pkt, 0);
831 831
832 /* Adjust for next transfer (if any) */ 832 /* Adjust for next transfer (if any) */
833 size -= dsize; 833 size -= dsize;
@@ -864,6 +864,29 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
864 return 0; 864 return 0;
865} 865}
866 866
867static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
868{
869 uint nents;
870 int err;
871
872 if (!sdiodev->sg_support)
873 return;
874
875 nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
876 nents += (nents >> 4) + 1;
877
878 WARN_ON(nents > sdiodev->max_segment_count);
879
880 brcmf_dbg(TRACE, "nents=%d\n", nents);
881 err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
882 if (err < 0) {
883 brcmf_err("allocation failed: disable scatter-gather");
884 sdiodev->sg_support = false;
885 }
886
887 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
888}
889
867static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 890static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
868{ 891{
869 if (sdiodev->bus) { 892 if (sdiodev->bus) {
@@ -881,6 +904,7 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
881 sdio_disable_func(sdiodev->func[1]); 904 sdio_disable_func(sdiodev->func[1]);
882 sdio_release_host(sdiodev->func[1]); 905 sdio_release_host(sdiodev->func[1]);
883 906
907 sg_free_table(&sdiodev->sgtable);
884 sdiodev->sbwad = 0; 908 sdiodev->sbwad = 0;
885 909
886 return 0; 910 return 0;
@@ -936,6 +960,11 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
936 SG_MAX_SINGLE_ALLOC); 960 SG_MAX_SINGLE_ALLOC);
937 sdiodev->max_segment_size = host->max_seg_size; 961 sdiodev->max_segment_size = host->max_seg_size;
938 962
963 /* allocate scatter-gather table. sg support
964 * will be disabled upon allocation failure.
965 */
966 brcmf_sdiod_sgtable_alloc(sdiodev);
967
939 /* try to attach to the target device */ 968 /* try to attach to the target device */
940 sdiodev->bus = brcmf_sdio_probe(sdiodev); 969 sdiodev->bus = brcmf_sdio_probe(sdiodev);
941 if (!sdiodev->bus) { 970 if (!sdiodev->bus) {
@@ -960,6 +989,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
960 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)}, 989 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
961 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, 990 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
962 SDIO_DEVICE_ID_BROADCOM_4335_4339)}, 991 SDIO_DEVICE_ID_BROADCOM_4335_4339)},
992 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)},
963 { /* end: all zeroes */ }, 993 { /* end: all zeroes */ },
964}; 994};
965MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); 995MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
@@ -1073,9 +1103,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
1073 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1103 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1074 int ret = 0; 1104 int ret = 0;
1075 1105
1076 brcmf_dbg(SDIO, "\n"); 1106 brcmf_dbg(SDIO, "Enter\n");
1077
1078 atomic_set(&sdiodev->suspend, true);
1079 1107
1080 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); 1108 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
1081 if (!(sdio_flags & MMC_PM_KEEP_POWER)) { 1109 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
@@ -1083,9 +1111,12 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
1083 return -EINVAL; 1111 return -EINVAL;
1084 } 1112 }
1085 1113
1114 atomic_set(&sdiodev->suspend, true);
1115
1086 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); 1116 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
1087 if (ret) { 1117 if (ret) {
1088 brcmf_err("Failed to set pm_flags\n"); 1118 brcmf_err("Failed to set pm_flags\n");
1119 atomic_set(&sdiodev->suspend, false);
1089 return ret; 1120 return ret;
1090 } 1121 }
1091 1122
@@ -1099,6 +1130,7 @@ static int brcmf_ops_sdio_resume(struct device *dev)
1099 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1130 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1100 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1131 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1101 1132
1133 brcmf_dbg(SDIO, "Enter\n");
1102 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1134 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
1103 atomic_set(&sdiodev->suspend, false); 1135 atomic_set(&sdiodev->suspend, false);
1104 return 0; 1136 return 0;
@@ -1115,14 +1147,15 @@ static struct sdio_driver brcmf_sdmmc_driver = {
1115 .remove = brcmf_ops_sdio_remove, 1147 .remove = brcmf_ops_sdio_remove,
1116 .name = BRCMFMAC_SDIO_PDATA_NAME, 1148 .name = BRCMFMAC_SDIO_PDATA_NAME,
1117 .id_table = brcmf_sdmmc_ids, 1149 .id_table = brcmf_sdmmc_ids,
1118#ifdef CONFIG_PM_SLEEP
1119 .drv = { 1150 .drv = {
1151 .owner = THIS_MODULE,
1152#ifdef CONFIG_PM_SLEEP
1120 .pm = &brcmf_sdio_pm_ops, 1153 .pm = &brcmf_sdio_pm_ops,
1121 },
1122#endif /* CONFIG_PM_SLEEP */ 1154#endif /* CONFIG_PM_SLEEP */
1155 },
1123}; 1156};
1124 1157
1125static int brcmf_sdio_pd_probe(struct platform_device *pdev) 1158static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
1126{ 1159{
1127 brcmf_dbg(SDIO, "Enter\n"); 1160 brcmf_dbg(SDIO, "Enter\n");
1128 1161
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
new file mode 100644
index 000000000000..df130ef53d1c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -0,0 +1,1034 @@
1/*
2 * Copyright (c) 2014 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#include <linux/kernel.h>
17#include <linux/delay.h>
18#include <linux/list.h>
19#include <linux/ssb/ssb_regs.h>
20#include <linux/bcma/bcma.h>
21#include <linux/bcma/bcma_regs.h>
22
23#include <defs.h>
24#include <soc.h>
25#include <brcm_hw_ids.h>
26#include <brcmu_utils.h>
27#include <chipcommon.h>
28#include "dhd_dbg.h"
29#include "chip.h"
30
31/* SOC Interconnect types (aka chip types) */
32#define SOCI_SB 0
33#define SOCI_AI 1
34
35/* PL-368 DMP definitions */
36#define DMP_DESC_TYPE_MSK 0x0000000F
37#define DMP_DESC_EMPTY 0x00000000
38#define DMP_DESC_VALID 0x00000001
39#define DMP_DESC_COMPONENT 0x00000001
40#define DMP_DESC_MASTER_PORT 0x00000003
41#define DMP_DESC_ADDRESS 0x00000005
42#define DMP_DESC_ADDRSIZE_GT32 0x00000008
43#define DMP_DESC_EOT 0x0000000F
44
45#define DMP_COMP_DESIGNER 0xFFF00000
46#define DMP_COMP_DESIGNER_S 20
47#define DMP_COMP_PARTNUM 0x000FFF00
48#define DMP_COMP_PARTNUM_S 8
49#define DMP_COMP_CLASS 0x000000F0
50#define DMP_COMP_CLASS_S 4
51#define DMP_COMP_REVISION 0xFF000000
52#define DMP_COMP_REVISION_S 24
53#define DMP_COMP_NUM_SWRAP 0x00F80000
54#define DMP_COMP_NUM_SWRAP_S 19
55#define DMP_COMP_NUM_MWRAP 0x0007C000
56#define DMP_COMP_NUM_MWRAP_S 14
57#define DMP_COMP_NUM_SPORT 0x00003E00
58#define DMP_COMP_NUM_SPORT_S 9
59#define DMP_COMP_NUM_MPORT 0x000001F0
60#define DMP_COMP_NUM_MPORT_S 4
61
62#define DMP_MASTER_PORT_UID 0x0000FF00
63#define DMP_MASTER_PORT_UID_S 8
64#define DMP_MASTER_PORT_NUM 0x000000F0
65#define DMP_MASTER_PORT_NUM_S 4
66
67#define DMP_SLAVE_ADDR_BASE 0xFFFFF000
68#define DMP_SLAVE_ADDR_BASE_S 12
69#define DMP_SLAVE_PORT_NUM 0x00000F00
70#define DMP_SLAVE_PORT_NUM_S 8
71#define DMP_SLAVE_TYPE 0x000000C0
72#define DMP_SLAVE_TYPE_S 6
73#define DMP_SLAVE_TYPE_SLAVE 0
74#define DMP_SLAVE_TYPE_BRIDGE 1
75#define DMP_SLAVE_TYPE_SWRAP 2
76#define DMP_SLAVE_TYPE_MWRAP 3
77#define DMP_SLAVE_SIZE_TYPE 0x00000030
78#define DMP_SLAVE_SIZE_TYPE_S 4
79#define DMP_SLAVE_SIZE_4K 0
80#define DMP_SLAVE_SIZE_8K 1
81#define DMP_SLAVE_SIZE_16K 2
82#define DMP_SLAVE_SIZE_DESC 3
83
84/* EROM CompIdentB */
85#define CIB_REV_MASK 0xff000000
86#define CIB_REV_SHIFT 24
87
88/* ARM CR4 core specific control flag bits */
89#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
90
91/* D11 core specific control flag bits */
92#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
93#define D11_BCMA_IOCTL_PHYRESET 0x0008
94
95/* chip core base & ramsize */
96/* bcm4329 */
97/* SDIO device core, ID 0x829 */
98#define BCM4329_CORE_BUS_BASE 0x18011000
99/* internal memory core, ID 0x80e */
100#define BCM4329_CORE_SOCRAM_BASE 0x18003000
101/* ARM Cortex M3 core, ID 0x82a */
102#define BCM4329_CORE_ARM_BASE 0x18002000
103#define BCM4329_RAMSIZE 0x48000
104
105/* bcm43143 */
106/* SDIO device core */
107#define BCM43143_CORE_BUS_BASE 0x18002000
108/* internal memory core */
109#define BCM43143_CORE_SOCRAM_BASE 0x18004000
110/* ARM Cortex M3 core, ID 0x82a */
111#define BCM43143_CORE_ARM_BASE 0x18003000
112#define BCM43143_RAMSIZE 0x70000
113
114#define CORE_SB(base, field) \
115 (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
116#define SBCOREREV(sbidh) \
117 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
118 ((sbidh) & SSB_IDHIGH_RCLO))
119
120struct sbconfig {
121 u32 PAD[2];
122 u32 sbipsflag; /* initiator port ocp slave flag */
123 u32 PAD[3];
124 u32 sbtpsflag; /* target port ocp slave flag */
125 u32 PAD[11];
126 u32 sbtmerrloga; /* (sonics >= 2.3) */
127 u32 PAD;
128 u32 sbtmerrlog; /* (sonics >= 2.3) */
129 u32 PAD[3];
130 u32 sbadmatch3; /* address match3 */
131 u32 PAD;
132 u32 sbadmatch2; /* address match2 */
133 u32 PAD;
134 u32 sbadmatch1; /* address match1 */
135 u32 PAD[7];
136 u32 sbimstate; /* initiator agent state */
137 u32 sbintvec; /* interrupt mask */
138 u32 sbtmstatelow; /* target state */
139 u32 sbtmstatehigh; /* target state */
140 u32 sbbwa0; /* bandwidth allocation table0 */
141 u32 PAD;
142 u32 sbimconfiglow; /* initiator configuration */
143 u32 sbimconfighigh; /* initiator configuration */
144 u32 sbadmatch0; /* address match0 */
145 u32 PAD;
146 u32 sbtmconfiglow; /* target configuration */
147 u32 sbtmconfighigh; /* target configuration */
148 u32 sbbconfig; /* broadcast configuration */
149 u32 PAD;
150 u32 sbbstate; /* broadcast state */
151 u32 PAD[3];
152 u32 sbactcnfg; /* activate configuration */
153 u32 PAD[3];
154 u32 sbflagst; /* current sbflags */
155 u32 PAD[3];
156 u32 sbidlow; /* identification */
157 u32 sbidhigh; /* identification */
158};
159
160struct brcmf_core_priv {
161 struct brcmf_core pub;
162 u32 wrapbase;
163 struct list_head list;
164 struct brcmf_chip_priv *chip;
165};
166
167/* ARM CR4 core specific control flag bits */
168#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
169
170/* D11 core specific control flag bits */
171#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
172#define D11_BCMA_IOCTL_PHYRESET 0x0008
173
174struct brcmf_chip_priv {
175 struct brcmf_chip pub;
176 const struct brcmf_buscore_ops *ops;
177 void *ctx;
178 /* assured first core is chipcommon, second core is buscore */
179 struct list_head cores;
180 u16 num_cores;
181
182 bool (*iscoreup)(struct brcmf_core_priv *core);
183 void (*coredisable)(struct brcmf_core_priv *core, u32 prereset,
184 u32 reset);
185 void (*resetcore)(struct brcmf_core_priv *core, u32 prereset, u32 reset,
186 u32 postreset);
187};
188
189static void brcmf_chip_sb_corerev(struct brcmf_chip_priv *ci,
190 struct brcmf_core *core)
191{
192 u32 regdata;
193
194 regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
195 core->rev = SBCOREREV(regdata);
196}
197
198static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv *core)
199{
200 struct brcmf_chip_priv *ci;
201 u32 regdata;
202 u32 address;
203
204 ci = core->chip;
205 address = CORE_SB(core->pub.base, sbtmstatelow);
206 regdata = ci->ops->read32(ci->ctx, address);
207 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
208 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
209 return SSB_TMSLOW_CLOCK == regdata;
210}
211
212static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv *core)
213{
214 struct brcmf_chip_priv *ci;
215 u32 regdata;
216 bool ret;
217
218 ci = core->chip;
219 regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
220 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
221
222 regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
223 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
224
225 return ret;
226}
227
228static void brcmf_chip_sb_coredisable(struct brcmf_core_priv *core,
229 u32 prereset, u32 reset)
230{
231 struct brcmf_chip_priv *ci;
232 u32 val, base;
233
234 ci = core->chip;
235 base = core->pub.base;
236 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
237 if (val & SSB_TMSLOW_RESET)
238 return;
239
240 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
241 if ((val & SSB_TMSLOW_CLOCK) != 0) {
242 /*
243 * set target reject and spin until busy is clear
244 * (preserve core-specific bits)
245 */
246 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
247 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
248 val | SSB_TMSLOW_REJECT);
249
250 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
251 udelay(1);
252 SPINWAIT((ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh))
253 & SSB_TMSHIGH_BUSY), 100000);
254
255 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
256 if (val & SSB_TMSHIGH_BUSY)
257 brcmf_err("core state still busy\n");
258
259 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
260 if (val & SSB_IDLOW_INITIATOR) {
261 val = ci->ops->read32(ci->ctx,
262 CORE_SB(base, sbimstate));
263 val |= SSB_IMSTATE_REJECT;
264 ci->ops->write32(ci->ctx,
265 CORE_SB(base, sbimstate), val);
266 val = ci->ops->read32(ci->ctx,
267 CORE_SB(base, sbimstate));
268 udelay(1);
269 SPINWAIT((ci->ops->read32(ci->ctx,
270 CORE_SB(base, sbimstate)) &
271 SSB_IMSTATE_BUSY), 100000);
272 }
273
274 /* set reset and reject while enabling the clocks */
275 val = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
276 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
277 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow), val);
278 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
279 udelay(10);
280
281 /* clear the initiator reject bit */
282 val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
283 if (val & SSB_IDLOW_INITIATOR) {
284 val = ci->ops->read32(ci->ctx,
285 CORE_SB(base, sbimstate));
286 val &= ~SSB_IMSTATE_REJECT;
287 ci->ops->write32(ci->ctx,
288 CORE_SB(base, sbimstate), val);
289 }
290 }
291
292 /* leave reset and reject asserted */
293 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
294 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
295 udelay(1);
296}
297
298static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
299 u32 prereset, u32 reset)
300{
301 struct brcmf_chip_priv *ci;
302 u32 regdata;
303
304 ci = core->chip;
305
306 /* if core is already in reset, just return */
307 regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
308 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
309 return;
310
311 /* configure reset */
312 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
313 prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
314 ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
315
316 /* put in reset */
317 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL,
318 BCMA_RESET_CTL_RESET);
319 usleep_range(10, 20);
320
321 /* wait till reset is 1 */
322 SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
323 BCMA_RESET_CTL_RESET, 300);
324
325 /* in-reset configure */
326 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
327 reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
328 ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
329}
330
331static void brcmf_chip_sb_resetcore(struct brcmf_core_priv *core, u32 prereset,
332 u32 reset, u32 postreset)
333{
334 struct brcmf_chip_priv *ci;
335 u32 regdata;
336 u32 base;
337
338 ci = core->chip;
339 base = core->pub.base;
340 /*
341 * Must do the disable sequence first to work for
342 * arbitrary current core state.
343 */
344 brcmf_chip_sb_coredisable(core, 0, 0);
345
346 /*
347 * Now do the initialization sequence.
348 * set reset while enabling the clock and
349 * forcing them on throughout the core
350 */
351 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
352 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
353 SSB_TMSLOW_RESET);
354 regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
355 udelay(1);
356
357 /* clear any serror */
358 regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
359 if (regdata & SSB_TMSHIGH_SERR)
360 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatehigh), 0);
361
362 regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbimstate));
363 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
364 regdata &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
365 ci->ops->write32(ci->ctx, CORE_SB(base, sbimstate), regdata);
366 }
367
368 /* clear reset and allow it to propagate throughout the core */
369 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
370 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
371 regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
372 udelay(1);
373
374 /* leave clock enabled */
375 ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
376 SSB_TMSLOW_CLOCK);
377 regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
378 udelay(1);
379}
380
381static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
382 u32 reset, u32 postreset)
383{
384 struct brcmf_chip_priv *ci;
385 int count;
386
387 ci = core->chip;
388
389 /* must disable first to work for arbitrary current core state */
390 brcmf_chip_ai_coredisable(core, prereset, reset);
391
392 count = 0;
393 while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
394 BCMA_RESET_CTL_RESET) {
395 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL, 0);
396 count++;
397 if (count > 50)
398 break;
399 usleep_range(40, 60);
400 }
401
402 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
403 postreset | BCMA_IOCTL_CLK);
404 ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
405}
406
407static char *brcmf_chip_name(uint chipid, char *buf, uint len)
408{
409 const char *fmt;
410
411 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
412 snprintf(buf, len, fmt, chipid);
413 return buf;
414}
415
416static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
417 u16 coreid, u32 base,
418 u32 wrapbase)
419{
420 struct brcmf_core_priv *core;
421
422 core = kzalloc(sizeof(*core), GFP_KERNEL);
423 if (!core)
424 return ERR_PTR(-ENOMEM);
425
426 core->pub.id = coreid;
427 core->pub.base = base;
428 core->chip = ci;
429 core->wrapbase = wrapbase;
430
431 list_add_tail(&core->list, &ci->cores);
432 return &core->pub;
433}
434
435#ifdef DEBUG
436/* safety check for chipinfo */
437static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
438{
439 struct brcmf_core_priv *core;
440 bool need_socram = false;
441 bool has_socram = false;
442 int idx = 1;
443
444 list_for_each_entry(core, &ci->cores, list) {
445 brcmf_dbg(INFO, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
446 idx++, core->pub.id, core->pub.rev, core->pub.base,
447 core->wrapbase);
448
449 switch (core->pub.id) {
450 case BCMA_CORE_ARM_CM3:
451 need_socram = true;
452 break;
453 case BCMA_CORE_INTERNAL_MEM:
454 has_socram = true;
455 break;
456 case BCMA_CORE_ARM_CR4:
457 if (ci->pub.rambase == 0) {
458 brcmf_err("RAM base not provided with ARM CR4 core\n");
459 return -ENOMEM;
460 }
461 break;
462 default:
463 break;
464 }
465 }
466
467 /* check RAM core presence for ARM CM3 core */
468 if (need_socram && !has_socram) {
469 brcmf_err("RAM core not provided with ARM CM3 core\n");
470 return -ENODEV;
471 }
472 return 0;
473}
474#else /* DEBUG */
475static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
476{
477 return 0;
478}
479#endif
480
481static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
482{
483 switch (ci->pub.chip) {
484 case BCM4329_CHIP_ID:
485 ci->pub.ramsize = BCM4329_RAMSIZE;
486 break;
487 case BCM43143_CHIP_ID:
488 ci->pub.ramsize = BCM43143_RAMSIZE;
489 break;
490 case BCM43241_CHIP_ID:
491 ci->pub.ramsize = 0x90000;
492 break;
493 case BCM4330_CHIP_ID:
494 ci->pub.ramsize = 0x48000;
495 break;
496 case BCM4334_CHIP_ID:
497 ci->pub.ramsize = 0x80000;
498 break;
499 case BCM4335_CHIP_ID:
500 ci->pub.ramsize = 0xc0000;
501 ci->pub.rambase = 0x180000;
502 break;
503 case BCM43362_CHIP_ID:
504 ci->pub.ramsize = 0x3c000;
505 break;
506 case BCM4339_CHIP_ID:
507 case BCM4354_CHIP_ID:
508 ci->pub.ramsize = 0xc0000;
509 ci->pub.rambase = 0x180000;
510 break;
511 default:
512 brcmf_err("unknown chip: %s\n", ci->pub.name);
513 break;
514 }
515}
516
517static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
518 u8 *type)
519{
520 u32 val;
521
522 /* read next descriptor */
523 val = ci->ops->read32(ci->ctx, *eromaddr);
524 *eromaddr += 4;
525
526 if (!type)
527 return val;
528
529 /* determine descriptor type */
530 *type = (val & DMP_DESC_TYPE_MSK);
531 if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
532 *type = DMP_DESC_ADDRESS;
533
534 return val;
535}
536
537static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
538 u32 *regbase, u32 *wrapbase)
539{
540 u8 desc;
541 u32 val;
542 u8 mpnum = 0;
543 u8 stype, sztype, wraptype;
544
545 *regbase = 0;
546 *wrapbase = 0;
547
548 val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
549 if (desc == DMP_DESC_MASTER_PORT) {
550 mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
551 wraptype = DMP_SLAVE_TYPE_MWRAP;
552 } else if (desc == DMP_DESC_ADDRESS) {
553 /* revert erom address */
554 *eromaddr -= 4;
555 wraptype = DMP_SLAVE_TYPE_SWRAP;
556 } else {
557 *eromaddr -= 4;
558 return -EILSEQ;
559 }
560
561 do {
562 /* locate address descriptor */
563 do {
564 val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
565 /* unexpected table end */
566 if (desc == DMP_DESC_EOT) {
567 *eromaddr -= 4;
568 return -EFAULT;
569 }
570 } while (desc != DMP_DESC_ADDRESS);
571
572 /* skip upper 32-bit address descriptor */
573 if (val & DMP_DESC_ADDRSIZE_GT32)
574 brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
575
576 sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
577
578 /* next size descriptor can be skipped */
579 if (sztype == DMP_SLAVE_SIZE_DESC) {
580 val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
581 /* skip upper size descriptor if present */
582 if (val & DMP_DESC_ADDRSIZE_GT32)
583 brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
584 }
585
586 /* only look for 4K register regions */
587 if (sztype != DMP_SLAVE_SIZE_4K)
588 continue;
589
590 stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
591
592 /* only regular slave and wrapper */
593 if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
594 *regbase = val & DMP_SLAVE_ADDR_BASE;
595 if (*wrapbase == 0 && stype == wraptype)
596 *wrapbase = val & DMP_SLAVE_ADDR_BASE;
597 } while (*regbase == 0 || *wrapbase == 0);
598
599 return 0;
600}
601
602static
603int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
604{
605 struct brcmf_core *core;
606 u32 eromaddr;
607 u8 desc_type = 0;
608 u32 val;
609 u16 id;
610 u8 nmp, nsp, nmw, nsw, rev;
611 u32 base, wrap;
612 int err;
613
614 eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
615
616 while (desc_type != DMP_DESC_EOT) {
617 val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
618 if (!(val & DMP_DESC_VALID))
619 continue;
620
621 if (desc_type == DMP_DESC_EMPTY)
622 continue;
623
624 /* need a component descriptor */
625 if (desc_type != DMP_DESC_COMPONENT)
626 continue;
627
628 id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
629
630 /* next descriptor must be component as well */
631 val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
632 if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
633 return -EFAULT;
634
635 /* only look at cores with master port(s) */
636 nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
637 nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
638 nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
639 nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
640 rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
641
642 /* need core with ports */
643 if (nmw + nsw == 0)
644 continue;
645
646 /* try to obtain register address info */
647 err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
648 if (err)
649 continue;
650
651 /* finally a core to be added */
652 core = brcmf_chip_add_core(ci, id, base, wrap);
653 if (IS_ERR(core))
654 return PTR_ERR(core);
655
656 core->rev = rev;
657 }
658
659 return 0;
660}
661
662static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
663{
664 struct brcmf_core *core;
665 u32 regdata;
666 u32 socitype;
667
668 /* Get CC core rev
669 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
670 * For different chiptypes or old sdio hosts w/o chipcommon,
671 * other ways of recognition should be added here.
672 */
673 regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
674 ci->pub.chip = regdata & CID_ID_MASK;
675 ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
676 socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
677
678 brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name));
679 brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n",
680 socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
681 ci->pub.chiprev);
682
683 if (socitype == SOCI_SB) {
684 if (ci->pub.chip != BCM4329_CHIP_ID) {
685 brcmf_err("SB chip is not supported\n");
686 return -ENODEV;
687 }
688 ci->iscoreup = brcmf_chip_sb_iscoreup;
689 ci->coredisable = brcmf_chip_sb_coredisable;
690 ci->resetcore = brcmf_chip_sb_resetcore;
691
692 core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
693 SI_ENUM_BASE, 0);
694 brcmf_chip_sb_corerev(ci, core);
695 core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
696 BCM4329_CORE_BUS_BASE, 0);
697 brcmf_chip_sb_corerev(ci, core);
698 core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
699 BCM4329_CORE_SOCRAM_BASE, 0);
700 brcmf_chip_sb_corerev(ci, core);
701 core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
702 BCM4329_CORE_ARM_BASE, 0);
703 brcmf_chip_sb_corerev(ci, core);
704
705 core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
706 brcmf_chip_sb_corerev(ci, core);
707 } else if (socitype == SOCI_AI) {
708 ci->iscoreup = brcmf_chip_ai_iscoreup;
709 ci->coredisable = brcmf_chip_ai_coredisable;
710 ci->resetcore = brcmf_chip_ai_resetcore;
711
712 brcmf_chip_dmp_erom_scan(ci);
713 } else {
714 brcmf_err("chip backplane type %u is not supported\n",
715 socitype);
716 return -ENODEV;
717 }
718
719 brcmf_chip_get_raminfo(ci);
720
721 return brcmf_chip_cores_check(ci);
722}
723
724static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
725{
726 struct brcmf_core *core;
727 struct brcmf_core_priv *cr4;
728 u32 val;
729
730
731 core = brcmf_chip_get_core(&chip->pub, id);
732 if (!core)
733 return;
734
735 switch (id) {
736 case BCMA_CORE_ARM_CM3:
737 brcmf_chip_coredisable(core, 0, 0);
738 break;
739 case BCMA_CORE_ARM_CR4:
740 cr4 = container_of(core, struct brcmf_core_priv, pub);
741
742 /* clear all IOCTL bits except HALT bit */
743 val = chip->ops->read32(chip->ctx, cr4->wrapbase + BCMA_IOCTL);
744 val &= ARMCR4_BCMA_IOCTL_CPUHALT;
745 brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
746 ARMCR4_BCMA_IOCTL_CPUHALT);
747 break;
748 default:
749 brcmf_err("unknown id: %u\n", id);
750 break;
751 }
752}
753
754static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
755{
756 struct brcmf_chip *pub;
757 struct brcmf_core_priv *cc;
758 u32 base;
759 u32 val;
760 int ret = 0;
761
762 pub = &chip->pub;
763 cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
764 base = cc->pub.base;
765
766 /* get chipcommon capabilites */
767 pub->cc_caps = chip->ops->read32(chip->ctx,
768 CORE_CC_REG(base, capabilities));
769
770 /* get pmu caps & rev */
771 if (pub->cc_caps & CC_CAP_PMU) {
772 val = chip->ops->read32(chip->ctx,
773 CORE_CC_REG(base, pmucapabilities));
774 pub->pmurev = val & PCAP_REV_MASK;
775 pub->pmucaps = val;
776 }
777
778 brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
779 cc->pub.rev, pub->pmurev, pub->pmucaps);
780
781 /* execute bus core specific setup */
782 if (chip->ops->setup)
783 ret = chip->ops->setup(chip->ctx, pub);
784
785 /*
786 * Make sure any on-chip ARM is off (in case strapping is wrong),
787 * or downloaded code was already running.
788 */
789 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
790 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
791 return ret;
792}
793
794struct brcmf_chip *brcmf_chip_attach(void *ctx,
795 const struct brcmf_buscore_ops *ops)
796{
797 struct brcmf_chip_priv *chip;
798 int err = 0;
799
800 if (WARN_ON(!ops->read32))
801 err = -EINVAL;
802 if (WARN_ON(!ops->write32))
803 err = -EINVAL;
804 if (WARN_ON(!ops->prepare))
805 err = -EINVAL;
806 if (WARN_ON(!ops->exit_dl))
807 err = -EINVAL;
808 if (err < 0)
809 return ERR_PTR(-EINVAL);
810
811 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
812 if (!chip)
813 return ERR_PTR(-ENOMEM);
814
815 INIT_LIST_HEAD(&chip->cores);
816 chip->num_cores = 0;
817 chip->ops = ops;
818 chip->ctx = ctx;
819
820 err = ops->prepare(ctx);
821 if (err < 0)
822 goto fail;
823
824 err = brcmf_chip_recognition(chip);
825 if (err < 0)
826 goto fail;
827
828 err = brcmf_chip_setup(chip);
829 if (err < 0)
830 goto fail;
831
832 return &chip->pub;
833
834fail:
835 brcmf_chip_detach(&chip->pub);
836 return ERR_PTR(err);
837}
838
839void brcmf_chip_detach(struct brcmf_chip *pub)
840{
841 struct brcmf_chip_priv *chip;
842 struct brcmf_core_priv *core;
843 struct brcmf_core_priv *tmp;
844
845 chip = container_of(pub, struct brcmf_chip_priv, pub);
846 list_for_each_entry_safe(core, tmp, &chip->cores, list) {
847 list_del(&core->list);
848 kfree(core);
849 }
850 kfree(chip);
851}
852
853struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
854{
855 struct brcmf_chip_priv *chip;
856 struct brcmf_core_priv *core;
857
858 chip = container_of(pub, struct brcmf_chip_priv, pub);
859 list_for_each_entry(core, &chip->cores, list)
860 if (core->pub.id == coreid)
861 return &core->pub;
862
863 return NULL;
864}
865
866struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
867{
868 struct brcmf_chip_priv *chip;
869 struct brcmf_core_priv *cc;
870
871 chip = container_of(pub, struct brcmf_chip_priv, pub);
872 cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
873 if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
874 return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
875 return &cc->pub;
876}
877
878bool brcmf_chip_iscoreup(struct brcmf_core *pub)
879{
880 struct brcmf_core_priv *core;
881
882 core = container_of(pub, struct brcmf_core_priv, pub);
883 return core->chip->iscoreup(core);
884}
885
886void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
887{
888 struct brcmf_core_priv *core;
889
890 core = container_of(pub, struct brcmf_core_priv, pub);
891 core->chip->coredisable(core, prereset, reset);
892}
893
894void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
895 u32 postreset)
896{
897 struct brcmf_core_priv *core;
898
899 core = container_of(pub, struct brcmf_core_priv, pub);
900 core->chip->resetcore(core, prereset, reset, postreset);
901}
902
903static void
904brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
905{
906 struct brcmf_core *core;
907
908 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
909 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
910 brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
911 D11_BCMA_IOCTL_PHYCLOCKEN,
912 D11_BCMA_IOCTL_PHYCLOCKEN,
913 D11_BCMA_IOCTL_PHYCLOCKEN);
914 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
915 brcmf_chip_resetcore(core, 0, 0, 0);
916}
917
918static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
919{
920 struct brcmf_core *core;
921
922 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
923 if (!brcmf_chip_iscoreup(core)) {
924 brcmf_err("SOCRAM core is down after reset?\n");
925 return false;
926 }
927
928 chip->ops->exit_dl(chip->ctx, &chip->pub, 0);
929
930 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
931 brcmf_chip_resetcore(core, 0, 0, 0);
932
933 return true;
934}
935
936static inline void
937brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
938{
939 struct brcmf_core *core;
940
941 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
942
943 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
944 brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
945 D11_BCMA_IOCTL_PHYCLOCKEN,
946 D11_BCMA_IOCTL_PHYCLOCKEN,
947 D11_BCMA_IOCTL_PHYCLOCKEN);
948}
949
950static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
951{
952 struct brcmf_core *core;
953
954 chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec);
955
956 /* restore ARM */
957 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
958 brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
959
960 return true;
961}
962
963void brcmf_chip_enter_download(struct brcmf_chip *pub)
964{
965 struct brcmf_chip_priv *chip;
966 struct brcmf_core *arm;
967
968 brcmf_dbg(TRACE, "Enter\n");
969
970 chip = container_of(pub, struct brcmf_chip_priv, pub);
971 arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
972 if (arm) {
973 brcmf_chip_cr4_enterdl(chip);
974 return;
975 }
976
977 brcmf_chip_cm3_enterdl(chip);
978}
979
980bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
981{
982 struct brcmf_chip_priv *chip;
983 struct brcmf_core *arm;
984
985 brcmf_dbg(TRACE, "Enter\n");
986
987 chip = container_of(pub, struct brcmf_chip_priv, pub);
988 arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
989 if (arm)
990 return brcmf_chip_cr4_exitdl(chip, rstvec);
991
992 return brcmf_chip_cm3_exitdl(chip);
993}
994
995bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
996{
997 u32 base, addr, reg, pmu_cc3_mask = ~0;
998 struct brcmf_chip_priv *chip;
999
1000 brcmf_dbg(TRACE, "Enter\n");
1001
1002 /* old chips with PMU version less than 17 don't support save restore */
1003 if (pub->pmurev < 17)
1004 return false;
1005
1006 base = brcmf_chip_get_chipcommon(pub)->base;
1007 chip = container_of(pub, struct brcmf_chip_priv, pub);
1008
1009 switch (pub->chip) {
1010 case BCM4354_CHIP_ID:
1011 /* explicitly check SR engine enable bit */
1012 pmu_cc3_mask = BIT(2);
1013 /* fall-through */
1014 case BCM43241_CHIP_ID:
1015 case BCM4335_CHIP_ID:
1016 case BCM4339_CHIP_ID:
1017 /* read PMU chipcontrol register 3 */
1018 addr = CORE_CC_REG(base, chipcontrol_addr);
1019 chip->ops->write32(chip->ctx, addr, 3);
1020 addr = CORE_CC_REG(base, chipcontrol_data);
1021 reg = chip->ops->read32(chip->ctx, addr);
1022 return (reg & pmu_cc3_mask) != 0;
1023 default:
1024 addr = CORE_CC_REG(base, pmucapabilities_ext);
1025 reg = chip->ops->read32(chip->ctx, addr);
1026 if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
1027 return false;
1028
1029 addr = CORE_CC_REG(base, retention_ctl);
1030 reg = chip->ops->read32(chip->ctx, addr);
1031 return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
1032 PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
1033 }
1034}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
new file mode 100644
index 000000000000..c32908da90c8
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2014 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 BRCMF_CHIP_H
17#define BRCMF_CHIP_H
18
19#include <linux/types.h>
20
21#define CORE_CC_REG(base, field) \
22 (base + offsetof(struct chipcregs, field))
23
24/**
25 * struct brcmf_chip - chip level information.
26 *
27 * @chip: chip identifier.
28 * @chiprev: chip revision.
29 * @cc_caps: chipcommon core capabilities.
30 * @pmucaps: PMU capabilities.
31 * @pmurev: PMU revision.
32 * @rambase: RAM base address (only applicable for ARM CR4 chips).
33 * @ramsize: amount of RAM on chip.
34 * @name: string representation of the chip identifier.
35 */
36struct brcmf_chip {
37 u32 chip;
38 u32 chiprev;
39 u32 cc_caps;
40 u32 pmucaps;
41 u32 pmurev;
42 u32 rambase;
43 u32 ramsize;
44 char name[8];
45};
46
47/**
48 * struct brcmf_core - core related information.
49 *
50 * @id: core identifier.
51 * @rev: core revision.
52 * @base: base address of core register space.
53 */
54struct brcmf_core {
55 u16 id;
56 u16 rev;
57 u32 base;
58};
59
60/**
61 * struct brcmf_buscore_ops - buscore specific callbacks.
62 *
63 * @read32: read 32-bit value over bus.
64 * @write32: write 32-bit value over bus.
65 * @prepare: prepare bus for core configuration.
66 * @setup: bus-specific core setup.
67 * @exit_dl: exit download state.
68 * The callback should use the provided @rstvec when non-zero.
69 */
70struct brcmf_buscore_ops {
71 u32 (*read32)(void *ctx, u32 addr);
72 void (*write32)(void *ctx, u32 addr, u32 value);
73 int (*prepare)(void *ctx);
74 int (*setup)(void *ctx, struct brcmf_chip *chip);
75 void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
76};
77
78struct brcmf_chip *brcmf_chip_attach(void *ctx,
79 const struct brcmf_buscore_ops *ops);
80void brcmf_chip_detach(struct brcmf_chip *chip);
81struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
82struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
83bool brcmf_chip_iscoreup(struct brcmf_core *core);
84void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
85void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
86 u32 postreset);
87void brcmf_chip_enter_download(struct brcmf_chip *ci);
88bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec);
89bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
90
91#endif /* BRCMF_AXIDMP_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index d4d966beb840..7d28cd385092 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1040,12 +1040,12 @@ void brcmf_detach(struct device *dev)
1040 1040
1041 brcmf_cfg80211_detach(drvr->config); 1041 brcmf_cfg80211_detach(drvr->config);
1042 1042
1043 brcmf_fws_deinit(drvr);
1044
1043 brcmf_bus_detach(drvr); 1045 brcmf_bus_detach(drvr);
1044 1046
1045 brcmf_proto_detach(drvr); 1047 brcmf_proto_detach(drvr);
1046 1048
1047 brcmf_fws_deinit(drvr);
1048
1049 brcmf_debugfs_detach(drvr); 1049 brcmf_debugfs_detach(drvr);
1050 bus_if->drvr = NULL; 1050 bus_if->drvr = NULL;
1051 kfree(drvr); 1051 kfree(drvr);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index ddaa9efd053d..13c89a0c4ba7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/mmc/sdio.h> 25#include <linux/mmc/sdio.h>
26#include <linux/mmc/sdio_ids.h>
26#include <linux/mmc/sdio_func.h> 27#include <linux/mmc/sdio_func.h>
27#include <linux/mmc/card.h> 28#include <linux/mmc/card.h>
28#include <linux/semaphore.h> 29#include <linux/semaphore.h>
@@ -40,7 +41,7 @@
40#include <brcm_hw_ids.h> 41#include <brcm_hw_ids.h>
41#include <soc.h> 42#include <soc.h>
42#include "sdio_host.h" 43#include "sdio_host.h"
43#include "sdio_chip.h" 44#include "chip.h"
44#include "nvram.h" 45#include "nvram.h"
45 46
46#define DCMD_RESP_TIMEOUT 2000 /* In milli second */ 47#define DCMD_RESP_TIMEOUT 2000 /* In milli second */
@@ -112,8 +113,6 @@ struct rte_console {
112#define BRCMF_TXBOUND 20 /* Default for max tx frames in 113#define BRCMF_TXBOUND 20 /* Default for max tx frames in
113 one scheduling */ 114 one scheduling */
114 115
115#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
116
117#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ 116#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
118 117
119#define MEMBLOCK 2048 /* Block size used for downloading 118#define MEMBLOCK 2048 /* Block size used for downloading
@@ -156,6 +155,34 @@ struct rte_console {
156/* manfid tuple length, include tuple, link bytes */ 155/* manfid tuple length, include tuple, link bytes */
157#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 156#define SBSDIO_CIS_MANFID_TUPLE_LEN 6
158 157
158#define CORE_BUS_REG(base, field) \
159 (base + offsetof(struct sdpcmd_regs, field))
160
161/* SDIO function 1 register CHIPCLKCSR */
162/* Force ALP request to backplane */
163#define SBSDIO_FORCE_ALP 0x01
164/* Force HT request to backplane */
165#define SBSDIO_FORCE_HT 0x02
166/* Force ILP request to backplane */
167#define SBSDIO_FORCE_ILP 0x04
168/* Make ALP ready (power up xtal) */
169#define SBSDIO_ALP_AVAIL_REQ 0x08
170/* Make HT ready (power up PLL) */
171#define SBSDIO_HT_AVAIL_REQ 0x10
172/* Squelch clock requests from HW */
173#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
174/* Status: ALP is ready */
175#define SBSDIO_ALP_AVAIL 0x40
176/* Status: HT is ready */
177#define SBSDIO_HT_AVAIL 0x80
178#define SBSDIO_CSR_MASK 0x1F
179#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
180#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
181#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
182#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
183#define SBSDIO_CLKAV(regval, alponly) \
184 (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
185
159/* intstatus */ 186/* intstatus */
160#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ 187#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
161#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ 188#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
@@ -276,7 +303,6 @@ struct rte_console {
276/* Flags for SDH calls */ 303/* Flags for SDH calls */
277#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) 304#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
278 305
279#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
280#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change 306#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
281 * when idle 307 * when idle
282 */ 308 */
@@ -433,10 +459,11 @@ struct brcmf_sdio {
433 bool alp_only; /* Don't use HT clock (ALP only) */ 459 bool alp_only; /* Don't use HT clock (ALP only) */
434 460
435 u8 *ctrl_frame_buf; 461 u8 *ctrl_frame_buf;
436 u32 ctrl_frame_len; 462 u16 ctrl_frame_len;
437 bool ctrl_frame_stat; 463 bool ctrl_frame_stat;
438 464
439 spinlock_t txqlock; 465 spinlock_t txq_lock; /* protect bus->txq */
466 struct semaphore tx_seq_lock; /* protect bus->tx_seq */
440 wait_queue_head_t ctrl_wait; 467 wait_queue_head_t ctrl_wait;
441 wait_queue_head_t dcmd_resp_wait; 468 wait_queue_head_t dcmd_resp_wait;
442 469
@@ -483,16 +510,58 @@ static const uint max_roundup = 512;
483 510
484#define ALIGNMENT 4 511#define ALIGNMENT 4
485 512
486static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
487module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
488MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
489
490enum brcmf_sdio_frmtype { 513enum brcmf_sdio_frmtype {
491 BRCMF_SDIO_FT_NORMAL, 514 BRCMF_SDIO_FT_NORMAL,
492 BRCMF_SDIO_FT_SUPER, 515 BRCMF_SDIO_FT_SUPER,
493 BRCMF_SDIO_FT_SUB, 516 BRCMF_SDIO_FT_SUB,
494}; 517};
495 518
519#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
520
521/* SDIO Pad drive strength to select value mappings */
522struct sdiod_drive_str {
523 u8 strength; /* Pad Drive Strength in mA */
524 u8 sel; /* Chip-specific select value */
525};
526
527/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
528static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
529 {32, 0x6},
530 {26, 0x7},
531 {22, 0x4},
532 {16, 0x5},
533 {12, 0x2},
534 {8, 0x3},
535 {4, 0x0},
536 {0, 0x1}
537};
538
539/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
540static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
541 {6, 0x7},
542 {5, 0x6},
543 {4, 0x5},
544 {3, 0x4},
545 {2, 0x2},
546 {1, 0x1},
547 {0, 0x0}
548};
549
550/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
551static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
552 {3, 0x3},
553 {2, 0x2},
554 {1, 0x1},
555 {0, 0x0} };
556
557/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
558static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
559 {16, 0x7},
560 {12, 0x5},
561 {8, 0x3},
562 {4, 0x1}
563};
564
496#define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin" 565#define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin"
497#define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt" 566#define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt"
498#define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin" 567#define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin"
@@ -511,6 +580,8 @@ enum brcmf_sdio_frmtype {
511#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" 580#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
512#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" 581#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
513#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" 582#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
583#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin"
584#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"
514 585
515MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME); 586MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
516MODULE_FIRMWARE(BCM43143_NVRAM_NAME); 587MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
@@ -530,6 +601,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
530MODULE_FIRMWARE(BCM43362_NVRAM_NAME); 601MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
531MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); 602MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
532MODULE_FIRMWARE(BCM4339_NVRAM_NAME); 603MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
604MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
605MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
533 606
534struct brcmf_firmware_names { 607struct brcmf_firmware_names {
535 u32 chipid; 608 u32 chipid;
@@ -555,7 +628,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
555 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, 628 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
556 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, 629 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
557 { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, 630 { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
558 { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) } 631 { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
632 { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
559}; 633};
560 634
561 635
@@ -618,27 +692,24 @@ static bool data_ok(struct brcmf_sdio *bus)
618 * Reads a register in the SDIO hardware block. This block occupies a series of 692 * Reads a register in the SDIO hardware block. This block occupies a series of
619 * adresses on the 32 bit backplane bus. 693 * adresses on the 32 bit backplane bus.
620 */ 694 */
621static int 695static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
622r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
623{ 696{
624 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 697 struct brcmf_core *core;
625 int ret; 698 int ret;
626 699
627 *regvar = brcmf_sdiod_regrl(bus->sdiodev, 700 core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
628 bus->ci->c_inf[idx].base + offset, &ret); 701 *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret);
629 702
630 return ret; 703 return ret;
631} 704}
632 705
633static int 706static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
634w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
635{ 707{
636 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 708 struct brcmf_core *core;
637 int ret; 709 int ret;
638 710
639 brcmf_sdiod_regwl(bus->sdiodev, 711 core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
640 bus->ci->c_inf[idx].base + reg_offset, 712 brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret);
641 regval, &ret);
642 713
643 return ret; 714 return ret;
644} 715}
@@ -650,16 +721,12 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
650 int err = 0; 721 int err = 0;
651 int try_cnt = 0; 722 int try_cnt = 0;
652 723
653 brcmf_dbg(TRACE, "Enter\n"); 724 brcmf_dbg(TRACE, "Enter: on=%d\n", on);
654 725
655 wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); 726 wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
656 /* 1st KSO write goes to AOS wake up core if device is asleep */ 727 /* 1st KSO write goes to AOS wake up core if device is asleep */
657 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 728 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
658 wr_val, &err); 729 wr_val, &err);
659 if (err) {
660 brcmf_err("SDIO_AOS KSO write error: %d\n", err);
661 return err;
662 }
663 730
664 if (on) { 731 if (on) {
665 /* device WAKEUP through KSO: 732 /* device WAKEUP through KSO:
@@ -689,18 +756,22 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
689 &err); 756 &err);
690 if (((rd_val & bmask) == cmp_val) && !err) 757 if (((rd_val & bmask) == cmp_val) && !err)
691 break; 758 break;
692 brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n", 759
693 try_cnt, MAX_KSO_ATTEMPTS, err);
694 udelay(KSO_WAIT_US); 760 udelay(KSO_WAIT_US);
695 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 761 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
696 wr_val, &err); 762 wr_val, &err);
697 } while (try_cnt++ < MAX_KSO_ATTEMPTS); 763 } while (try_cnt++ < MAX_KSO_ATTEMPTS);
698 764
765 if (try_cnt > 2)
766 brcmf_dbg(SDIO, "try_cnt=%d rd_val=0x%x err=%d\n", try_cnt,
767 rd_val, err);
768
769 if (try_cnt > MAX_KSO_ATTEMPTS)
770 brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
771
699 return err; 772 return err;
700} 773}
701 774
702#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
703
704#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) 775#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
705 776
706/* Turn backplane clock on or off */ 777/* Turn backplane clock on or off */
@@ -799,7 +870,6 @@ static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
799 } 870 }
800#endif /* defined (DEBUG) */ 871#endif /* defined (DEBUG) */
801 872
802 bus->activity = true;
803 } else { 873 } else {
804 clkreq = 0; 874 clkreq = 0;
805 875
@@ -899,8 +969,9 @@ static int
899brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) 969brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
900{ 970{
901 int err = 0; 971 int err = 0;
902 brcmf_dbg(TRACE, "Enter\n"); 972 u8 clkcsr;
903 brcmf_dbg(SDIO, "request %s currently %s\n", 973
974 brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
904 (sleep ? "SLEEP" : "WAKE"), 975 (sleep ? "SLEEP" : "WAKE"),
905 (bus->sleeping ? "SLEEP" : "WAKE")); 976 (bus->sleeping ? "SLEEP" : "WAKE"));
906 977
@@ -917,8 +988,20 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
917 atomic_read(&bus->ipend) > 0 || 988 atomic_read(&bus->ipend) > 0 ||
918 (!atomic_read(&bus->fcstate) && 989 (!atomic_read(&bus->fcstate) &&
919 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 990 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
920 data_ok(bus))) 991 data_ok(bus))) {
921 return -EBUSY; 992 err = -EBUSY;
993 goto done;
994 }
995
996 clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
997 SBSDIO_FUNC1_CHIPCLKCSR,
998 &err);
999 if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
1000 brcmf_dbg(SDIO, "no clock, set ALP\n");
1001 brcmf_sdiod_regwb(bus->sdiodev,
1002 SBSDIO_FUNC1_CHIPCLKCSR,
1003 SBSDIO_ALP_AVAIL_REQ, &err);
1004 }
922 err = brcmf_sdio_kso_control(bus, false); 1005 err = brcmf_sdio_kso_control(bus, false);
923 /* disable watchdog */ 1006 /* disable watchdog */
924 if (!err) 1007 if (!err)
@@ -935,7 +1018,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
935 } else { 1018 } else {
936 brcmf_err("error while changing bus sleep state %d\n", 1019 brcmf_err("error while changing bus sleep state %d\n",
937 err); 1020 err);
938 return err; 1021 goto done;
939 } 1022 }
940 } 1023 }
941 1024
@@ -947,11 +1030,92 @@ end:
947 } else { 1030 } else {
948 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); 1031 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
949 } 1032 }
950 1033done:
1034 brcmf_dbg(SDIO, "Exit: err=%d\n", err);
951 return err; 1035 return err;
952 1036
953} 1037}
954 1038
1039#ifdef DEBUG
1040static inline bool brcmf_sdio_valid_shared_address(u32 addr)
1041{
1042 return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
1043}
1044
1045static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
1046 struct sdpcm_shared *sh)
1047{
1048 u32 addr;
1049 int rv;
1050 u32 shaddr = 0;
1051 struct sdpcm_shared_le sh_le;
1052 __le32 addr_le;
1053
1054 shaddr = bus->ci->rambase + bus->ramsize - 4;
1055
1056 /*
1057 * Read last word in socram to determine
1058 * address of sdpcm_shared structure
1059 */
1060 sdio_claim_host(bus->sdiodev->func[1]);
1061 brcmf_sdio_bus_sleep(bus, false, false);
1062 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
1063 sdio_release_host(bus->sdiodev->func[1]);
1064 if (rv < 0)
1065 return rv;
1066
1067 addr = le32_to_cpu(addr_le);
1068
1069 brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
1070
1071 /*
1072 * Check if addr is valid.
1073 * NVRAM length at the end of memory should have been overwritten.
1074 */
1075 if (!brcmf_sdio_valid_shared_address(addr)) {
1076 brcmf_err("invalid sdpcm_shared address 0x%08X\n",
1077 addr);
1078 return -EINVAL;
1079 }
1080
1081 /* Read hndrte_shared structure */
1082 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
1083 sizeof(struct sdpcm_shared_le));
1084 if (rv < 0)
1085 return rv;
1086
1087 /* Endianness */
1088 sh->flags = le32_to_cpu(sh_le.flags);
1089 sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
1090 sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
1091 sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
1092 sh->assert_line = le32_to_cpu(sh_le.assert_line);
1093 sh->console_addr = le32_to_cpu(sh_le.console_addr);
1094 sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
1095
1096 if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
1097 brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
1098 SDPCM_SHARED_VERSION,
1099 sh->flags & SDPCM_SHARED_VERSION_MASK);
1100 return -EPROTO;
1101 }
1102
1103 return 0;
1104}
1105
1106static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
1107{
1108 struct sdpcm_shared sh;
1109
1110 if (brcmf_sdio_readshared(bus, &sh) == 0)
1111 bus->console_addr = sh.console_addr;
1112}
1113#else
1114static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
1115{
1116}
1117#endif /* DEBUG */
1118
955static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) 1119static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
956{ 1120{
957 u32 intstatus = 0; 1121 u32 intstatus = 0;
@@ -995,6 +1159,12 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
995 else 1159 else
996 brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n", 1160 brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n",
997 bus->sdpcm_ver); 1161 bus->sdpcm_ver);
1162
1163 /*
1164 * Retrieve console state address now that firmware should have
1165 * updated it.
1166 */
1167 brcmf_sdio_get_console_addr(bus);
998 } 1168 }
999 1169
1000 /* 1170 /*
@@ -1083,6 +1253,28 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1083 bus->cur_read.len = 0; 1253 bus->cur_read.len = 0;
1084} 1254}
1085 1255
1256static void brcmf_sdio_txfail(struct brcmf_sdio *bus)
1257{
1258 struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
1259 u8 i, hi, lo;
1260
1261 /* On failure, abort the command and terminate the frame */
1262 brcmf_err("sdio error, abort command and terminate frame\n");
1263 bus->sdcnt.tx_sderrs++;
1264
1265 brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
1266 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
1267 bus->sdcnt.f1regdata++;
1268
1269 for (i = 0; i < 3; i++) {
1270 hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
1271 lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
1272 bus->sdcnt.f1regdata += 2;
1273 if ((hi == 0) && (lo == 0))
1274 break;
1275 }
1276}
1277
1086/* return total length of buffer chain */ 1278/* return total length of buffer chain */
1087static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus) 1279static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus)
1088{ 1280{
@@ -1955,7 +2147,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
1955 memcpy(pkt_pad->data, 2147 memcpy(pkt_pad->data,
1956 pkt->data + pkt->len - tail_chop, 2148 pkt->data + pkt->len - tail_chop,
1957 tail_chop); 2149 tail_chop);
1958 *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; 2150 *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
1959 skb_trim(pkt, pkt->len - tail_chop); 2151 skb_trim(pkt, pkt->len - tail_chop);
1960 skb_trim(pkt_pad, tail_pad + tail_chop); 2152 skb_trim(pkt_pad, tail_pad + tail_chop);
1961 __skb_queue_after(pktq, pkt, pkt_pad); 2153 __skb_queue_after(pktq, pkt, pkt_pad);
@@ -2003,7 +2195,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2003 * already properly aligned and does not 2195 * already properly aligned and does not
2004 * need an sdpcm header. 2196 * need an sdpcm header.
2005 */ 2197 */
2006 if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) 2198 if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
2007 continue; 2199 continue;
2008 2200
2009 /* align packet data pointer */ 2201 /* align packet data pointer */
@@ -2037,10 +2229,10 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2037 if (BRCMF_BYTES_ON() && 2229 if (BRCMF_BYTES_ON() &&
2038 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || 2230 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
2039 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) 2231 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
2040 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, 2232 brcmf_dbg_hex_dump(true, pkt_next->data, hd_info.len,
2041 "Tx Frame:\n"); 2233 "Tx Frame:\n");
2042 else if (BRCMF_HDRS_ON()) 2234 else if (BRCMF_HDRS_ON())
2043 brcmf_dbg_hex_dump(true, pkt_next, 2235 brcmf_dbg_hex_dump(true, pkt_next->data,
2044 head_pad + bus->tx_hdrlen, 2236 head_pad + bus->tx_hdrlen,
2045 "Tx Header:\n"); 2237 "Tx Header:\n");
2046 } 2238 }
@@ -2067,11 +2259,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2067 u8 *hdr; 2259 u8 *hdr;
2068 u32 dat_offset; 2260 u32 dat_offset;
2069 u16 tail_pad; 2261 u16 tail_pad;
2070 u32 dummy_flags, chop_len; 2262 u16 dummy_flags, chop_len;
2071 struct sk_buff *pkt_next, *tmp, *pkt_prev; 2263 struct sk_buff *pkt_next, *tmp, *pkt_prev;
2072 2264
2073 skb_queue_walk_safe(pktq, pkt_next, tmp) { 2265 skb_queue_walk_safe(pktq, pkt_next, tmp) {
2074 dummy_flags = *(u32 *)(pkt_next->cb); 2266 dummy_flags = *(u16 *)(pkt_next->cb);
2075 if (dummy_flags & ALIGN_SKB_FLAG) { 2267 if (dummy_flags & ALIGN_SKB_FLAG) {
2076 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; 2268 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
2077 if (chop_len) { 2269 if (chop_len) {
@@ -2100,7 +2292,6 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2100 uint chan) 2292 uint chan)
2101{ 2293{
2102 int ret; 2294 int ret;
2103 int i;
2104 struct sk_buff *pkt_next, *tmp; 2295 struct sk_buff *pkt_next, *tmp;
2105 2296
2106 brcmf_dbg(TRACE, "Enter\n"); 2297 brcmf_dbg(TRACE, "Enter\n");
@@ -2113,28 +2304,9 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2113 ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq); 2304 ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
2114 bus->sdcnt.f2txdata++; 2305 bus->sdcnt.f2txdata++;
2115 2306
2116 if (ret < 0) { 2307 if (ret < 0)
2117 /* On failure, abort the command and terminate the frame */ 2308 brcmf_sdio_txfail(bus);
2118 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2119 ret);
2120 bus->sdcnt.tx_sderrs++;
2121 2309
2122 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2123 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2124 SFC_WF_TERM, NULL);
2125 bus->sdcnt.f1regdata++;
2126
2127 for (i = 0; i < 3; i++) {
2128 u8 hi, lo;
2129 hi = brcmf_sdiod_regrb(bus->sdiodev,
2130 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2131 lo = brcmf_sdiod_regrb(bus->sdiodev,
2132 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2133 bus->sdcnt.f1regdata += 2;
2134 if ((hi == 0) && (lo == 0))
2135 break;
2136 }
2137 }
2138 sdio_release_host(bus->sdiodev->func[1]); 2310 sdio_release_host(bus->sdiodev->func[1]);
2139 2311
2140done: 2312done:
@@ -2164,13 +2336,15 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2164 /* Send frames until the limit or some other event */ 2336 /* Send frames until the limit or some other event */
2165 for (cnt = 0; (cnt < maxframes) && data_ok(bus);) { 2337 for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
2166 pkt_num = 1; 2338 pkt_num = 1;
2167 __skb_queue_head_init(&pktq); 2339 if (down_interruptible(&bus->tx_seq_lock))
2340 return cnt;
2168 if (bus->txglom) 2341 if (bus->txglom)
2169 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, 2342 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
2170 brcmf_sdio_txglomsz); 2343 bus->sdiodev->txglomsz);
2171 pkt_num = min_t(u32, pkt_num, 2344 pkt_num = min_t(u32, pkt_num,
2172 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)); 2345 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
2173 spin_lock_bh(&bus->txqlock); 2346 __skb_queue_head_init(&pktq);
2347 spin_lock_bh(&bus->txq_lock);
2174 for (i = 0; i < pkt_num; i++) { 2348 for (i = 0; i < pkt_num; i++) {
2175 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, 2349 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
2176 &prec_out); 2350 &prec_out);
@@ -2178,15 +2352,19 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2178 break; 2352 break;
2179 __skb_queue_tail(&pktq, pkt); 2353 __skb_queue_tail(&pktq, pkt);
2180 } 2354 }
2181 spin_unlock_bh(&bus->txqlock); 2355 spin_unlock_bh(&bus->txq_lock);
2182 if (i == 0) 2356 if (i == 0) {
2357 up(&bus->tx_seq_lock);
2183 break; 2358 break;
2359 }
2184 2360
2185 ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); 2361 ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
2362 up(&bus->tx_seq_lock);
2363
2186 cnt += i; 2364 cnt += i;
2187 2365
2188 /* In poll mode, need to check for other events */ 2366 /* In poll mode, need to check for other events */
2189 if (!bus->intr && cnt) { 2367 if (!bus->intr) {
2190 /* Check device status, signal pending interrupt */ 2368 /* Check device status, signal pending interrupt */
2191 sdio_claim_host(bus->sdiodev->func[1]); 2369 sdio_claim_host(bus->sdiodev->func[1]);
2192 ret = r_sdreg32(bus, &intstatus, 2370 ret = r_sdreg32(bus, &intstatus,
@@ -2211,6 +2389,68 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2211 return cnt; 2389 return cnt;
2212} 2390}
2213 2391
2392static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio *bus, u8 *frame, u16 len)
2393{
2394 u8 doff;
2395 u16 pad;
2396 uint retries = 0;
2397 struct brcmf_sdio_hdrinfo hd_info = {0};
2398 int ret;
2399
2400 brcmf_dbg(TRACE, "Enter\n");
2401
2402 /* Back the pointer to make room for bus header */
2403 frame -= bus->tx_hdrlen;
2404 len += bus->tx_hdrlen;
2405
2406 /* Add alignment padding (optional for ctl frames) */
2407 doff = ((unsigned long)frame % bus->head_align);
2408 if (doff) {
2409 frame -= doff;
2410 len += doff;
2411 memset(frame + bus->tx_hdrlen, 0, doff);
2412 }
2413
2414 /* Round send length to next SDIO block */
2415 pad = 0;
2416 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
2417 pad = bus->blocksize - (len % bus->blocksize);
2418 if ((pad > bus->roundup) || (pad >= bus->blocksize))
2419 pad = 0;
2420 } else if (len % bus->head_align) {
2421 pad = bus->head_align - (len % bus->head_align);
2422 }
2423 len += pad;
2424
2425 hd_info.len = len - pad;
2426 hd_info.channel = SDPCM_CONTROL_CHANNEL;
2427 hd_info.dat_offset = doff + bus->tx_hdrlen;
2428 hd_info.seq_num = bus->tx_seq;
2429 hd_info.lastfrm = true;
2430 hd_info.tail_pad = pad;
2431 brcmf_sdio_hdpack(bus, frame, &hd_info);
2432
2433 if (bus->txglom)
2434 brcmf_sdio_update_hwhdr(frame, len);
2435
2436 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
2437 frame, len, "Tx Frame:\n");
2438 brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
2439 BRCMF_HDRS_ON(),
2440 frame, min_t(u16, len, 16), "TxHdr:\n");
2441
2442 do {
2443 ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
2444
2445 if (ret < 0)
2446 brcmf_sdio_txfail(bus);
2447 else
2448 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2449 } while (ret < 0 && retries++ < TXRETRIES);
2450
2451 return ret;
2452}
2453
2214static void brcmf_sdio_bus_stop(struct device *dev) 2454static void brcmf_sdio_bus_stop(struct device *dev)
2215{ 2455{
2216 u32 local_hostintmask; 2456 u32 local_hostintmask;
@@ -2292,21 +2532,29 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus)
2292 } 2532 }
2293} 2533}
2294 2534
2535static void atomic_orr(int val, atomic_t *v)
2536{
2537 int old_val;
2538
2539 old_val = atomic_read(v);
2540 while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
2541 old_val = atomic_read(v);
2542}
2543
2295static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) 2544static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2296{ 2545{
2297 u8 idx; 2546 struct brcmf_core *buscore;
2298 u32 addr; 2547 u32 addr;
2299 unsigned long val; 2548 unsigned long val;
2300 int n, ret; 2549 int ret;
2301 2550
2302 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 2551 buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
2303 addr = bus->ci->c_inf[idx].base + 2552 addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
2304 offsetof(struct sdpcmd_regs, intstatus);
2305 2553
2306 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); 2554 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
2307 bus->sdcnt.f1regdata++; 2555 bus->sdcnt.f1regdata++;
2308 if (ret != 0) 2556 if (ret != 0)
2309 val = 0; 2557 return ret;
2310 2558
2311 val &= bus->hostintmask; 2559 val &= bus->hostintmask;
2312 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE)); 2560 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
@@ -2315,13 +2563,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2315 if (val) { 2563 if (val) {
2316 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); 2564 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
2317 bus->sdcnt.f1regdata++; 2565 bus->sdcnt.f1regdata++;
2318 } 2566 atomic_orr(val, &bus->intstatus);
2319
2320 if (ret) {
2321 atomic_set(&bus->intstatus, 0);
2322 } else if (val) {
2323 for_each_set_bit(n, &val, 32)
2324 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2325 } 2567 }
2326 2568
2327 return ret; 2569 return ret;
@@ -2331,10 +2573,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2331{ 2573{
2332 u32 newstatus = 0; 2574 u32 newstatus = 0;
2333 unsigned long intstatus; 2575 unsigned long intstatus;
2334 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
2335 uint txlimit = bus->txbound; /* Tx frames to send before resched */ 2576 uint txlimit = bus->txbound; /* Tx frames to send before resched */
2336 uint framecnt = 0; /* Temporary counter of tx/rx frames */ 2577 uint framecnt; /* Temporary counter of tx/rx frames */
2337 int err = 0, n; 2578 int err = 0;
2338 2579
2339 brcmf_dbg(TRACE, "Enter\n"); 2580 brcmf_dbg(TRACE, "Enter\n");
2340 2581
@@ -2431,70 +2672,38 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2431 intstatus &= ~I_HMB_FRAME_IND; 2672 intstatus &= ~I_HMB_FRAME_IND;
2432 2673
2433 /* On frame indication, read available frames */ 2674 /* On frame indication, read available frames */
2434 if (PKT_AVAILABLE() && bus->clkstate == CLK_AVAIL) { 2675 if ((intstatus & I_HMB_FRAME_IND) && (bus->clkstate == CLK_AVAIL)) {
2435 framecnt = brcmf_sdio_readframes(bus, rxlimit); 2676 brcmf_sdio_readframes(bus, bus->rxbound);
2436 if (!bus->rxpending) 2677 if (!bus->rxpending)
2437 intstatus &= ~I_HMB_FRAME_IND; 2678 intstatus &= ~I_HMB_FRAME_IND;
2438 rxlimit -= min(framecnt, rxlimit);
2439 } 2679 }
2440 2680
2441 /* Keep still-pending events for next scheduling */ 2681 /* Keep still-pending events for next scheduling */
2442 if (intstatus) { 2682 if (intstatus)
2443 for_each_set_bit(n, &intstatus, 32) 2683 atomic_orr(intstatus, &bus->intstatus);
2444 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2445 }
2446 2684
2447 brcmf_sdio_clrintr(bus); 2685 brcmf_sdio_clrintr(bus);
2448 2686
2449 if (data_ok(bus) && bus->ctrl_frame_stat && 2687 if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
2450 (bus->clkstate == CLK_AVAIL)) { 2688 (down_interruptible(&bus->tx_seq_lock) == 0)) {
2451 int i; 2689 if (data_ok(bus)) {
2452 2690 sdio_claim_host(bus->sdiodev->func[1]);
2453 sdio_claim_host(bus->sdiodev->func[1]); 2691 err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
2454 err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf, 2692 bus->ctrl_frame_len);
2455 (u32)bus->ctrl_frame_len); 2693 sdio_release_host(bus->sdiodev->func[1]);
2456
2457 if (err < 0) {
2458 /* On failure, abort the command and
2459 terminate the frame */
2460 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2461 err);
2462 bus->sdcnt.tx_sderrs++;
2463
2464 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2465
2466 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2467 SFC_WF_TERM, &err);
2468 bus->sdcnt.f1regdata++;
2469
2470 for (i = 0; i < 3; i++) {
2471 u8 hi, lo;
2472 hi = brcmf_sdiod_regrb(bus->sdiodev,
2473 SBSDIO_FUNC1_WFRAMEBCHI,
2474 &err);
2475 lo = brcmf_sdiod_regrb(bus->sdiodev,
2476 SBSDIO_FUNC1_WFRAMEBCLO,
2477 &err);
2478 bus->sdcnt.f1regdata += 2;
2479 if ((hi == 0) && (lo == 0))
2480 break;
2481 }
2482 2694
2483 } else { 2695 bus->ctrl_frame_stat = false;
2484 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; 2696 brcmf_sdio_wait_event_wakeup(bus);
2485 } 2697 }
2486 sdio_release_host(bus->sdiodev->func[1]); 2698 up(&bus->tx_seq_lock);
2487 bus->ctrl_frame_stat = false;
2488 brcmf_sdio_wait_event_wakeup(bus);
2489 } 2699 }
2490 /* Send queued frames (limit 1 if rx may still be pending) */ 2700 /* Send queued frames (limit 1 if rx may still be pending) */
2491 else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) && 2701 if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
2492 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit 2702 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit &&
2493 && data_ok(bus)) { 2703 data_ok(bus)) {
2494 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) : 2704 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
2495 txlimit; 2705 txlimit;
2496 framecnt = brcmf_sdio_sendfromq(bus, framecnt); 2706 brcmf_sdio_sendfromq(bus, framecnt);
2497 txlimit -= framecnt;
2498 } 2707 }
2499 2708
2500 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) { 2709 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
@@ -2504,19 +2713,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2504 atomic_read(&bus->ipend) > 0 || 2713 atomic_read(&bus->ipend) > 0 ||
2505 (!atomic_read(&bus->fcstate) && 2714 (!atomic_read(&bus->fcstate) &&
2506 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 2715 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
2507 data_ok(bus)) || PKT_AVAILABLE()) { 2716 data_ok(bus))) {
2508 atomic_inc(&bus->dpc_tskcnt); 2717 atomic_inc(&bus->dpc_tskcnt);
2509 } 2718 }
2510
2511 /* If we're done for now, turn off clock request. */
2512 if ((bus->clkstate != CLK_PENDING)
2513 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
2514 bus->activity = false;
2515 brcmf_dbg(SDIO, "idle state\n");
2516 sdio_claim_host(bus->sdiodev->func[1]);
2517 brcmf_sdio_bus_sleep(bus, true, false);
2518 sdio_release_host(bus->sdiodev->func[1]);
2519 }
2520} 2719}
2521 2720
2522static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev) 2721static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
@@ -2531,15 +2730,12 @@ static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
2531static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) 2730static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2532{ 2731{
2533 int ret = -EBADE; 2732 int ret = -EBADE;
2534 uint datalen, prec; 2733 uint prec;
2535 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2734 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2536 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2735 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2537 struct brcmf_sdio *bus = sdiodev->bus; 2736 struct brcmf_sdio *bus = sdiodev->bus;
2538 ulong flags;
2539 2737
2540 brcmf_dbg(TRACE, "Enter\n"); 2738 brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
2541
2542 datalen = pkt->len;
2543 2739
2544 /* Add space for the header */ 2740 /* Add space for the header */
2545 skb_push(pkt, bus->tx_hdrlen); 2741 skb_push(pkt, bus->tx_hdrlen);
@@ -2553,7 +2749,9 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2553 bus->sdcnt.fcqueued++; 2749 bus->sdcnt.fcqueued++;
2554 2750
2555 /* Priority based enq */ 2751 /* Priority based enq */
2556 spin_lock_irqsave(&bus->txqlock, flags); 2752 spin_lock_bh(&bus->txq_lock);
2753 /* reset bus_flags in packet cb */
2754 *(u16 *)(pkt->cb) = 0;
2557 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { 2755 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
2558 skb_pull(pkt, bus->tx_hdrlen); 2756 skb_pull(pkt, bus->tx_hdrlen);
2559 brcmf_err("out of bus->txq !!!\n"); 2757 brcmf_err("out of bus->txq !!!\n");
@@ -2566,7 +2764,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2566 bus->txoff = true; 2764 bus->txoff = true;
2567 brcmf_txflowblock(bus->sdiodev->dev, true); 2765 brcmf_txflowblock(bus->sdiodev->dev, true);
2568 } 2766 }
2569 spin_unlock_irqrestore(&bus->txqlock, flags); 2767 spin_unlock_bh(&bus->txq_lock);
2570 2768
2571#ifdef DEBUG 2769#ifdef DEBUG
2572 if (pktq_plen(&bus->txq, prec) > qcount[prec]) 2770 if (pktq_plen(&bus->txq, prec) > qcount[prec])
@@ -2661,110 +2859,27 @@ break2:
2661} 2859}
2662#endif /* DEBUG */ 2860#endif /* DEBUG */
2663 2861
2664static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2665{
2666 int i;
2667 int ret;
2668
2669 bus->ctrl_frame_stat = false;
2670 ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
2671
2672 if (ret < 0) {
2673 /* On failure, abort the command and terminate the frame */
2674 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2675 ret);
2676 bus->sdcnt.tx_sderrs++;
2677
2678 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2679
2680 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2681 SFC_WF_TERM, NULL);
2682 bus->sdcnt.f1regdata++;
2683
2684 for (i = 0; i < 3; i++) {
2685 u8 hi, lo;
2686 hi = brcmf_sdiod_regrb(bus->sdiodev,
2687 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2688 lo = brcmf_sdiod_regrb(bus->sdiodev,
2689 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2690 bus->sdcnt.f1regdata += 2;
2691 if (hi == 0 && lo == 0)
2692 break;
2693 }
2694 return ret;
2695 }
2696
2697 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2698
2699 return ret;
2700}
2701
2702static int 2862static int
2703brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) 2863brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2704{ 2864{
2705 u8 *frame;
2706 u16 len, pad;
2707 uint retries = 0;
2708 u8 doff = 0;
2709 int ret = -1;
2710 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2865 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2711 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2866 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2712 struct brcmf_sdio *bus = sdiodev->bus; 2867 struct brcmf_sdio *bus = sdiodev->bus;
2713 struct brcmf_sdio_hdrinfo hd_info = {0}; 2868 int ret = -1;
2714 2869
2715 brcmf_dbg(TRACE, "Enter\n"); 2870 brcmf_dbg(TRACE, "Enter\n");
2716 2871
2717 /* Back the pointer to make a room for bus header */ 2872 if (down_interruptible(&bus->tx_seq_lock))
2718 frame = msg - bus->tx_hdrlen; 2873 return -EINTR;
2719 len = (msglen += bus->tx_hdrlen);
2720
2721 /* Add alignment padding (optional for ctl frames) */
2722 doff = ((unsigned long)frame % bus->head_align);
2723 if (doff) {
2724 frame -= doff;
2725 len += doff;
2726 msglen += doff;
2727 memset(frame, 0, doff + bus->tx_hdrlen);
2728 }
2729 /* precondition: doff < bus->head_align */
2730 doff += bus->tx_hdrlen;
2731
2732 /* Round send length to next SDIO block */
2733 pad = 0;
2734 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
2735 pad = bus->blocksize - (len % bus->blocksize);
2736 if ((pad > bus->roundup) || (pad >= bus->blocksize))
2737 pad = 0;
2738 } else if (len % bus->head_align) {
2739 pad = bus->head_align - (len % bus->head_align);
2740 }
2741 len += pad;
2742
2743 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
2744
2745 /* Make sure backplane clock is on */
2746 sdio_claim_host(bus->sdiodev->func[1]);
2747 brcmf_sdio_bus_sleep(bus, false, false);
2748 sdio_release_host(bus->sdiodev->func[1]);
2749
2750 hd_info.len = (u16)msglen;
2751 hd_info.channel = SDPCM_CONTROL_CHANNEL;
2752 hd_info.dat_offset = doff;
2753 hd_info.seq_num = bus->tx_seq;
2754 hd_info.lastfrm = true;
2755 hd_info.tail_pad = pad;
2756 brcmf_sdio_hdpack(bus, frame, &hd_info);
2757
2758 if (bus->txglom)
2759 brcmf_sdio_update_hwhdr(frame, len);
2760 2874
2761 if (!data_ok(bus)) { 2875 if (!data_ok(bus)) {
2762 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", 2876 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
2763 bus->tx_max, bus->tx_seq); 2877 bus->tx_max, bus->tx_seq);
2764 bus->ctrl_frame_stat = true; 2878 up(&bus->tx_seq_lock);
2765 /* Send from dpc */ 2879 /* Send from dpc */
2766 bus->ctrl_frame_buf = frame; 2880 bus->ctrl_frame_buf = msg;
2767 bus->ctrl_frame_len = len; 2881 bus->ctrl_frame_len = msglen;
2882 bus->ctrl_frame_stat = true;
2768 2883
2769 wait_event_interruptible_timeout(bus->ctrl_wait, 2884 wait_event_interruptible_timeout(bus->ctrl_wait,
2770 !bus->ctrl_frame_stat, 2885 !bus->ctrl_frame_stat,
@@ -2775,31 +2890,18 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2775 ret = 0; 2890 ret = 0;
2776 } else { 2891 } else {
2777 brcmf_dbg(SDIO, "ctrl_frame_stat == true\n"); 2892 brcmf_dbg(SDIO, "ctrl_frame_stat == true\n");
2893 bus->ctrl_frame_stat = false;
2894 if (down_interruptible(&bus->tx_seq_lock))
2895 return -EINTR;
2778 ret = -1; 2896 ret = -1;
2779 } 2897 }
2780 } 2898 }
2781
2782 if (ret == -1) { 2899 if (ret == -1) {
2783 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
2784 frame, len, "Tx Frame:\n");
2785 brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
2786 BRCMF_HDRS_ON(),
2787 frame, min_t(u16, len, 16), "TxHdr:\n");
2788
2789 do {
2790 sdio_claim_host(bus->sdiodev->func[1]);
2791 ret = brcmf_sdio_tx_frame(bus, frame, len);
2792 sdio_release_host(bus->sdiodev->func[1]);
2793 } while (ret < 0 && retries++ < TXRETRIES);
2794 }
2795
2796 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
2797 atomic_read(&bus->dpc_tskcnt) == 0) {
2798 bus->activity = false;
2799 sdio_claim_host(bus->sdiodev->func[1]); 2900 sdio_claim_host(bus->sdiodev->func[1]);
2800 brcmf_dbg(INFO, "idle\n"); 2901 brcmf_sdio_bus_sleep(bus, false, false);
2801 brcmf_sdio_clkctl(bus, CLK_NONE, true); 2902 ret = brcmf_sdio_tx_ctrlframe(bus, msg, msglen);
2802 sdio_release_host(bus->sdiodev->func[1]); 2903 sdio_release_host(bus->sdiodev->func[1]);
2904 up(&bus->tx_seq_lock);
2803 } 2905 }
2804 2906
2805 if (ret) 2907 if (ret)
@@ -2811,72 +2913,6 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2811} 2913}
2812 2914
2813#ifdef DEBUG 2915#ifdef DEBUG
2814static inline bool brcmf_sdio_valid_shared_address(u32 addr)
2815{
2816 return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
2817}
2818
2819static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2820 struct sdpcm_shared *sh)
2821{
2822 u32 addr;
2823 int rv;
2824 u32 shaddr = 0;
2825 struct sdpcm_shared_le sh_le;
2826 __le32 addr_le;
2827
2828 shaddr = bus->ci->rambase + bus->ramsize - 4;
2829
2830 /*
2831 * Read last word in socram to determine
2832 * address of sdpcm_shared structure
2833 */
2834 sdio_claim_host(bus->sdiodev->func[1]);
2835 brcmf_sdio_bus_sleep(bus, false, false);
2836 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
2837 sdio_release_host(bus->sdiodev->func[1]);
2838 if (rv < 0)
2839 return rv;
2840
2841 addr = le32_to_cpu(addr_le);
2842
2843 brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
2844
2845 /*
2846 * Check if addr is valid.
2847 * NVRAM length at the end of memory should have been overwritten.
2848 */
2849 if (!brcmf_sdio_valid_shared_address(addr)) {
2850 brcmf_err("invalid sdpcm_shared address 0x%08X\n",
2851 addr);
2852 return -EINVAL;
2853 }
2854
2855 /* Read hndrte_shared structure */
2856 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
2857 sizeof(struct sdpcm_shared_le));
2858 if (rv < 0)
2859 return rv;
2860
2861 /* Endianness */
2862 sh->flags = le32_to_cpu(sh_le.flags);
2863 sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
2864 sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
2865 sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
2866 sh->assert_line = le32_to_cpu(sh_le.assert_line);
2867 sh->console_addr = le32_to_cpu(sh_le.console_addr);
2868 sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
2869
2870 if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
2871 brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
2872 SDPCM_SHARED_VERSION,
2873 sh->flags & SDPCM_SHARED_VERSION_MASK);
2874 return -EPROTO;
2875 }
2876
2877 return 0;
2878}
2879
2880static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, 2916static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
2881 struct sdpcm_shared *sh, char __user *data, 2917 struct sdpcm_shared *sh, char __user *data,
2882 size_t count) 2918 size_t count)
@@ -3106,6 +3142,8 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3106 debugfs_create_file("forensics", S_IRUGO, dentry, bus, 3142 debugfs_create_file("forensics", S_IRUGO, dentry, bus,
3107 &brcmf_sdio_forensic_ops); 3143 &brcmf_sdio_forensic_ops);
3108 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); 3144 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
3145 debugfs_create_u32("console_interval", 0644, dentry,
3146 &bus->console_interval);
3109} 3147}
3110#else 3148#else
3111static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) 3149static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
@@ -3224,32 +3262,17 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus,
3224 const struct firmware *fw) 3262 const struct firmware *fw)
3225{ 3263{
3226 int err; 3264 int err;
3227 int offset;
3228 int address;
3229 int len;
3230 3265
3231 brcmf_dbg(TRACE, "Enter\n"); 3266 brcmf_dbg(TRACE, "Enter\n");
3232 3267
3233 err = 0; 3268 err = brcmf_sdiod_ramrw(bus->sdiodev, true, bus->ci->rambase,
3234 offset = 0; 3269 (u8 *)fw->data, fw->size);
3235 address = bus->ci->rambase; 3270 if (err)
3236 while (offset < fw->size) { 3271 brcmf_err("error %d on writing %d membytes at 0x%08x\n",
3237 len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK : 3272 err, (int)fw->size, bus->ci->rambase);
3238 fw->size - offset; 3273 else if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
3239 err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, 3274 (u8 *)fw->data, fw->size))
3240 (u8 *)&fw->data[offset], len); 3275 err = -EIO;
3241 if (err) {
3242 brcmf_err("error %d on writing %d membytes at 0x%08x\n",
3243 err, len, address);
3244 return err;
3245 }
3246 offset += len;
3247 address += len;
3248 }
3249 if (!err)
3250 if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
3251 (u8 *)fw->data, fw->size))
3252 err = -EIO;
3253 3276
3254 return err; 3277 return err;
3255} 3278}
@@ -3292,7 +3315,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
3292 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 3315 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
3293 3316
3294 /* Keep arm in reset */ 3317 /* Keep arm in reset */
3295 brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci); 3318 brcmf_chip_enter_download(bus->ci);
3296 3319
3297 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN); 3320 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);
3298 if (fw == NULL) { 3321 if (fw == NULL) {
@@ -3324,7 +3347,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
3324 } 3347 }
3325 3348
3326 /* Take arm out of reset */ 3349 /* Take arm out of reset */
3327 if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) { 3350 if (!brcmf_chip_exit_download(bus->ci, rstvec)) {
3328 brcmf_err("error getting out of ARM core reset\n"); 3351 brcmf_err("error getting out of ARM core reset\n");
3329 goto err; 3352 goto err;
3330 } 3353 }
@@ -3339,40 +3362,6 @@ err:
3339 return bcmerror; 3362 return bcmerror;
3340} 3363}
3341 3364
3342static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus)
3343{
3344 u32 addr, reg, pmu_cc3_mask = ~0;
3345 int err;
3346
3347 brcmf_dbg(TRACE, "Enter\n");
3348
3349 /* old chips with PMU version less than 17 don't support save restore */
3350 if (bus->ci->pmurev < 17)
3351 return false;
3352
3353 switch (bus->ci->chip) {
3354 case BCM43241_CHIP_ID:
3355 case BCM4335_CHIP_ID:
3356 case BCM4339_CHIP_ID:
3357 /* read PMU chipcontrol register 3 */
3358 addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr);
3359 brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL);
3360 addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data);
3361 reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
3362 return (reg & pmu_cc3_mask) != 0;
3363 default:
3364 addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext);
3365 reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err);
3366 if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
3367 return false;
3368
3369 addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl);
3370 reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
3371 return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
3372 PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
3373 }
3374}
3375
3376static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) 3365static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
3377{ 3366{
3378 int err = 0; 3367 int err = 0;
@@ -3424,7 +3413,7 @@ static int brcmf_sdio_kso_init(struct brcmf_sdio *bus)
3424 brcmf_dbg(TRACE, "Enter\n"); 3413 brcmf_dbg(TRACE, "Enter\n");
3425 3414
3426 /* KSO bit added in SDIO core rev 12 */ 3415 /* KSO bit added in SDIO core rev 12 */
3427 if (bus->ci->c_inf[1].rev < 12) 3416 if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
3428 return 0; 3417 return 0;
3429 3418
3430 val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); 3419 val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
@@ -3455,15 +3444,13 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
3455 struct brcmf_sdio *bus = sdiodev->bus; 3444 struct brcmf_sdio *bus = sdiodev->bus;
3456 uint pad_size; 3445 uint pad_size;
3457 u32 value; 3446 u32 value;
3458 u8 idx;
3459 int err; 3447 int err;
3460 3448
3461 /* the commands below use the terms tx and rx from 3449 /* the commands below use the terms tx and rx from
3462 * a device perspective, ie. bus:txglom affects the 3450 * a device perspective, ie. bus:txglom affects the
3463 * bus transfers from device to host. 3451 * bus transfers from device to host.
3464 */ 3452 */
3465 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 3453 if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) {
3466 if (bus->ci->c_inf[idx].rev < 12) {
3467 /* for sdio core rev < 12, disable txgloming */ 3454 /* for sdio core rev < 12, disable txgloming */
3468 value = 0; 3455 value = 0;
3469 err = brcmf_iovar_data_set(dev, "bus:txglom", &value, 3456 err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
@@ -3570,7 +3557,7 @@ static int brcmf_sdio_bus_init(struct device *dev)
3570 ret = -ENODEV; 3557 ret = -ENODEV;
3571 } 3558 }
3572 3559
3573 if (brcmf_sdio_sr_capable(bus)) { 3560 if (brcmf_chip_sr_capable(bus->ci)) {
3574 brcmf_sdio_sr_init(bus); 3561 brcmf_sdio_sr_init(bus);
3575 } else { 3562 } else {
3576 /* Restore previous clock setting */ 3563 /* Restore previous clock setting */
@@ -3714,11 +3701,175 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3714 datawork); 3701 datawork);
3715 3702
3716 while (atomic_read(&bus->dpc_tskcnt)) { 3703 while (atomic_read(&bus->dpc_tskcnt)) {
3704 atomic_set(&bus->dpc_tskcnt, 0);
3717 brcmf_sdio_dpc(bus); 3705 brcmf_sdio_dpc(bus);
3718 atomic_dec(&bus->dpc_tskcnt);
3719 } 3706 }
3720} 3707}
3721 3708
3709static void
3710brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
3711 struct brcmf_chip *ci, u32 drivestrength)
3712{
3713 const struct sdiod_drive_str *str_tab = NULL;
3714 u32 str_mask;
3715 u32 str_shift;
3716 u32 base;
3717 u32 i;
3718 u32 drivestrength_sel = 0;
3719 u32 cc_data_temp;
3720 u32 addr;
3721
3722 if (!(ci->cc_caps & CC_CAP_PMU))
3723 return;
3724
3725 switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
3726 case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
3727 str_tab = sdiod_drvstr_tab1_1v8;
3728 str_mask = 0x00003800;
3729 str_shift = 11;
3730 break;
3731 case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
3732 str_tab = sdiod_drvstr_tab6_1v8;
3733 str_mask = 0x00001800;
3734 str_shift = 11;
3735 break;
3736 case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
3737 /* note: 43143 does not support tristate */
3738 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
3739 if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
3740 str_tab = sdiod_drvstr_tab2_3v3;
3741 str_mask = 0x00000007;
3742 str_shift = 0;
3743 } else
3744 brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
3745 ci->name, drivestrength);
3746 break;
3747 case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
3748 str_tab = sdiod_drive_strength_tab5_1v8;
3749 str_mask = 0x00003800;
3750 str_shift = 11;
3751 break;
3752 default:
3753 brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
3754 ci->name, ci->chiprev, ci->pmurev);
3755 break;
3756 }
3757
3758 if (str_tab != NULL) {
3759 for (i = 0; str_tab[i].strength != 0; i++) {
3760 if (drivestrength >= str_tab[i].strength) {
3761 drivestrength_sel = str_tab[i].sel;
3762 break;
3763 }
3764 }
3765 base = brcmf_chip_get_chipcommon(ci)->base;
3766 addr = CORE_CC_REG(base, chipcontrol_addr);
3767 brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
3768 cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
3769 cc_data_temp &= ~str_mask;
3770 drivestrength_sel <<= str_shift;
3771 cc_data_temp |= drivestrength_sel;
3772 brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
3773
3774 brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
3775 str_tab[i].strength, drivestrength, cc_data_temp);
3776 }
3777}
3778
3779static int brcmf_sdio_buscoreprep(void *ctx)
3780{
3781 struct brcmf_sdio_dev *sdiodev = ctx;
3782 int err = 0;
3783 u8 clkval, clkset;
3784
3785 /* Try forcing SDIO core to do ALPAvail request only */
3786 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
3787 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
3788 if (err) {
3789 brcmf_err("error writing for HT off\n");
3790 return err;
3791 }
3792
3793 /* If register supported, wait for ALPAvail and then force ALP */
3794 /* This may take up to 15 milliseconds */
3795 clkval = brcmf_sdiod_regrb(sdiodev,
3796 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
3797
3798 if ((clkval & ~SBSDIO_AVBITS) != clkset) {
3799 brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
3800 clkset, clkval);
3801 return -EACCES;
3802 }
3803
3804 SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
3805 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
3806 !SBSDIO_ALPAV(clkval)),
3807 PMU_MAX_TRANSITION_DLY);
3808 if (!SBSDIO_ALPAV(clkval)) {
3809 brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
3810 clkval);
3811 return -EBUSY;
3812 }
3813
3814 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
3815 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
3816 udelay(65);
3817
3818 /* Also, disable the extra SDIO pull-ups */
3819 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
3820
3821 return 0;
3822}
3823
3824static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
3825 u32 rstvec)
3826{
3827 struct brcmf_sdio_dev *sdiodev = ctx;
3828 struct brcmf_core *core;
3829 u32 reg_addr;
3830
3831 /* clear all interrupts */
3832 core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
3833 reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
3834 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
3835
3836 if (rstvec)
3837 /* Write reset vector to address 0 */
3838 brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
3839 sizeof(rstvec));
3840}
3841
3842static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
3843{
3844 struct brcmf_sdio_dev *sdiodev = ctx;
3845 u32 val, rev;
3846
3847 val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
3848 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
3849 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
3850 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
3851 if (rev >= 2) {
3852 val &= ~CID_ID_MASK;
3853 val |= BCM4339_CHIP_ID;
3854 }
3855 }
3856 return val;
3857}
3858
3859static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val)
3860{
3861 struct brcmf_sdio_dev *sdiodev = ctx;
3862
3863 brcmf_sdiod_regwl(sdiodev, addr, val, NULL);
3864}
3865
3866static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
3867 .prepare = brcmf_sdio_buscoreprep,
3868 .exit_dl = brcmf_sdio_buscore_exitdl,
3869 .read32 = brcmf_sdio_buscore_read32,
3870 .write32 = brcmf_sdio_buscore_write32,
3871};
3872
3722static bool 3873static bool
3723brcmf_sdio_probe_attach(struct brcmf_sdio *bus) 3874brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3724{ 3875{
@@ -3734,7 +3885,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3734 brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); 3885 brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
3735 3886
3736 /* 3887 /*
3737 * Force PLL off until brcmf_sdio_chip_attach() 3888 * Force PLL off until brcmf_chip_attach()
3738 * programs PLL control regs 3889 * programs PLL control regs
3739 */ 3890 */
3740 3891
@@ -3755,8 +3906,10 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3755 */ 3906 */
3756 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN); 3907 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
3757 3908
3758 if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) { 3909 bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops);
3759 brcmf_err("brcmf_sdio_chip_attach failed!\n"); 3910 if (IS_ERR(bus->ci)) {
3911 brcmf_err("brcmf_chip_attach failed!\n");
3912 bus->ci = NULL;
3760 goto fail; 3913 goto fail;
3761 } 3914 }
3762 3915
@@ -3769,7 +3922,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3769 drivestrength = bus->sdiodev->pdata->drive_strength; 3922 drivestrength = bus->sdiodev->pdata->drive_strength;
3770 else 3923 else
3771 drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; 3924 drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
3772 brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); 3925 brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
3773 3926
3774 /* Get info on the SOCRAM cores... */ 3927 /* Get info on the SOCRAM cores... */
3775 bus->ramsize = bus->ci->ramsize; 3928 bus->ramsize = bus->ci->ramsize;
@@ -3792,24 +3945,18 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3792 goto fail; 3945 goto fail;
3793 3946
3794 /* set PMUControl so a backplane reset does PMU state reload */ 3947 /* set PMUControl so a backplane reset does PMU state reload */
3795 reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base, 3948 reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base,
3796 pmucontrol); 3949 pmucontrol);
3797 reg_val = brcmf_sdiod_regrl(bus->sdiodev, 3950 reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
3798 reg_addr,
3799 &err);
3800 if (err) 3951 if (err)
3801 goto fail; 3952 goto fail;
3802 3953
3803 reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); 3954 reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
3804 3955
3805 brcmf_sdiod_regwl(bus->sdiodev, 3956 brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err);
3806 reg_addr,
3807 reg_val,
3808 &err);
3809 if (err) 3957 if (err)
3810 goto fail; 3958 goto fail;
3811 3959
3812
3813 sdio_release_host(bus->sdiodev->func[1]); 3960 sdio_release_host(bus->sdiodev->func[1]);
3814 3961
3815 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3962 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
@@ -3849,6 +3996,7 @@ brcmf_sdio_watchdog_thread(void *data)
3849 brcmf_sdio_bus_watchdog(bus); 3996 brcmf_sdio_bus_watchdog(bus);
3850 /* Count the tick for reference */ 3997 /* Count the tick for reference */
3851 bus->sdcnt.tickcnt++; 3998 bus->sdcnt.tickcnt++;
3999 reinit_completion(&bus->watchdog_wait);
3852 } else 4000 } else
3853 break; 4001 break;
3854 } 4002 }
@@ -3925,7 +4073,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
3925 } 4073 }
3926 4074
3927 spin_lock_init(&bus->rxctl_lock); 4075 spin_lock_init(&bus->rxctl_lock);
3928 spin_lock_init(&bus->txqlock); 4076 spin_lock_init(&bus->txq_lock);
4077 sema_init(&bus->tx_seq_lock, 1);
3929 init_waitqueue_head(&bus->ctrl_wait); 4078 init_waitqueue_head(&bus->ctrl_wait);
3930 init_waitqueue_head(&bus->dcmd_resp_wait); 4079 init_waitqueue_head(&bus->dcmd_resp_wait);
3931 4080
@@ -4024,14 +4173,14 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4024 /* De-register interrupt handler */ 4173 /* De-register interrupt handler */
4025 brcmf_sdiod_intr_unregister(bus->sdiodev); 4174 brcmf_sdiod_intr_unregister(bus->sdiodev);
4026 4175
4027 cancel_work_sync(&bus->datawork);
4028 if (bus->brcmf_wq)
4029 destroy_workqueue(bus->brcmf_wq);
4030
4031 if (bus->sdiodev->bus_if->drvr) { 4176 if (bus->sdiodev->bus_if->drvr) {
4032 brcmf_detach(bus->sdiodev->dev); 4177 brcmf_detach(bus->sdiodev->dev);
4033 } 4178 }
4034 4179
4180 cancel_work_sync(&bus->datawork);
4181 if (bus->brcmf_wq)
4182 destroy_workqueue(bus->brcmf_wq);
4183
4035 if (bus->ci) { 4184 if (bus->ci) {
4036 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { 4185 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
4037 sdio_claim_host(bus->sdiodev->func[1]); 4186 sdio_claim_host(bus->sdiodev->func[1]);
@@ -4042,12 +4191,11 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4042 * all necessary cores. 4191 * all necessary cores.
4043 */ 4192 */
4044 msleep(20); 4193 msleep(20);
4045 brcmf_sdio_chip_enter_download(bus->sdiodev, 4194 brcmf_chip_enter_download(bus->ci);
4046 bus->ci);
4047 brcmf_sdio_clkctl(bus, CLK_NONE, false); 4195 brcmf_sdio_clkctl(bus, CLK_NONE, false);
4048 sdio_release_host(bus->sdiodev->func[1]); 4196 sdio_release_host(bus->sdiodev->func[1]);
4049 } 4197 }
4050 brcmf_sdio_chip_detach(&bus->ci); 4198 brcmf_chip_detach(bus->ci);
4051 } 4199 }
4052 4200
4053 kfree(bus->rxbuf); 4201 kfree(bus->rxbuf);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 22adbe311d20..59a5af5bf994 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -124,7 +124,8 @@ brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data)
124} 124}
125 125
126static u32 126static u32
127brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen) 127brcmf_create_iovar(char *name, const char *data, u32 datalen,
128 char *buf, u32 buflen)
128{ 129{
129 u32 len; 130 u32 len;
130 131
@@ -144,7 +145,7 @@ brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen)
144 145
145 146
146s32 147s32
147brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, 148brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
148 u32 len) 149 u32 len)
149{ 150{
150 struct brcmf_pub *drvr = ifp->drvr; 151 struct brcmf_pub *drvr = ifp->drvr;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
index 77eae86e55c2..a30be683f4a1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
@@ -83,7 +83,7 @@ s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
83s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); 83s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
84s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data); 84s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data);
85 85
86s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, 86s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
87 u32 len); 87 u32 len);
88s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, 88s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
89 u32 len); 89 u32 len);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index af17a5bc8b83..614e4888504f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -48,6 +48,11 @@
48 48
49#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ 49#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
50 50
51/* OBSS Coex Auto/On/Off */
52#define BRCMF_OBSS_COEX_AUTO (-1)
53#define BRCMF_OBSS_COEX_OFF 0
54#define BRCMF_OBSS_COEX_ON 1
55
51enum brcmf_fil_p2p_if_types { 56enum brcmf_fil_p2p_if_types {
52 BRCMF_FIL_P2P_IF_CLIENT, 57 BRCMF_FIL_P2P_IF_CLIENT,
53 BRCMF_FIL_P2P_IF_GO, 58 BRCMF_FIL_P2P_IF_GO,
@@ -87,6 +92,11 @@ struct brcmf_fil_bss_enable_le {
87 __le32 enable; 92 __le32 enable;
88}; 93};
89 94
95struct brcmf_fil_bwcap_le {
96 __le32 band;
97 __le32 bw_cap;
98};
99
90/** 100/**
91 * struct tdls_iovar - common structure for tdls iovars. 101 * struct tdls_iovar - common structure for tdls iovars.
92 * 102 *
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index fc4f98b275d7..f3445ac627e4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -797,7 +797,8 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
797 /* SOCIAL CHANNELS 1, 6, 11 */ 797 /* SOCIAL CHANNELS 1, 6, 11 */
798 search_state = WL_P2P_DISC_ST_SEARCH; 798 search_state = WL_P2P_DISC_ST_SEARCH;
799 brcmf_dbg(INFO, "P2P SEARCH PHASE START\n"); 799 brcmf_dbg(INFO, "P2P SEARCH PHASE START\n");
800 } else if (dev != NULL && vif->mode == WL_MODE_AP) { 800 } else if (dev != NULL &&
801 vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
801 /* If you are already a GO, then do SEARCH only */ 802 /* If you are already a GO, then do SEARCH only */
802 brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n"); 803 brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n");
803 search_state = WL_P2P_DISC_ST_SEARCH; 804 search_state = WL_P2P_DISC_ST_SEARCH;
@@ -2256,7 +2257,6 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2256 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 2257 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2257 struct brcmf_cfg80211_vif *vif; 2258 struct brcmf_cfg80211_vif *vif;
2258 enum brcmf_fil_p2p_if_types iftype; 2259 enum brcmf_fil_p2p_if_types iftype;
2259 enum wl_mode mode;
2260 int err; 2260 int err;
2261 2261
2262 if (brcmf_cfg80211_vif_event_armed(cfg)) 2262 if (brcmf_cfg80211_vif_event_armed(cfg))
@@ -2267,11 +2267,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2267 switch (type) { 2267 switch (type) {
2268 case NL80211_IFTYPE_P2P_CLIENT: 2268 case NL80211_IFTYPE_P2P_CLIENT:
2269 iftype = BRCMF_FIL_P2P_IF_CLIENT; 2269 iftype = BRCMF_FIL_P2P_IF_CLIENT;
2270 mode = WL_MODE_BSS;
2271 break; 2270 break;
2272 case NL80211_IFTYPE_P2P_GO: 2271 case NL80211_IFTYPE_P2P_GO:
2273 iftype = BRCMF_FIL_P2P_IF_GO; 2272 iftype = BRCMF_FIL_P2P_IF_GO;
2274 mode = WL_MODE_AP;
2275 break; 2273 break;
2276 case NL80211_IFTYPE_P2P_DEVICE: 2274 case NL80211_IFTYPE_P2P_DEVICE:
2277 return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy, 2275 return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
deleted file mode 100644
index 82bf3c5d3cdc..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ /dev/null
@@ -1,972 +0,0 @@
1/*
2 * Copyright (c) 2011 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/* ***** SDIO interface chip backplane handle functions ***** */
17
18#include <linux/types.h>
19#include <linux/netdevice.h>
20#include <linux/mmc/card.h>
21#include <linux/mmc/sdio_func.h>
22#include <linux/mmc/sdio_ids.h>
23#include <linux/ssb/ssb_regs.h>
24#include <linux/bcma/bcma.h>
25
26#include <chipcommon.h>
27#include <brcm_hw_ids.h>
28#include <brcmu_wifi.h>
29#include <brcmu_utils.h>
30#include <soc.h>
31#include "dhd_dbg.h"
32#include "sdio_host.h"
33#include "sdio_chip.h"
34
35/* chip core base & ramsize */
36/* bcm4329 */
37/* SDIO device core, ID 0x829 */
38#define BCM4329_CORE_BUS_BASE 0x18011000
39/* internal memory core, ID 0x80e */
40#define BCM4329_CORE_SOCRAM_BASE 0x18003000
41/* ARM Cortex M3 core, ID 0x82a */
42#define BCM4329_CORE_ARM_BASE 0x18002000
43#define BCM4329_RAMSIZE 0x48000
44
45/* bcm43143 */
46/* SDIO device core */
47#define BCM43143_CORE_BUS_BASE 0x18002000
48/* internal memory core */
49#define BCM43143_CORE_SOCRAM_BASE 0x18004000
50/* ARM Cortex M3 core, ID 0x82a */
51#define BCM43143_CORE_ARM_BASE 0x18003000
52#define BCM43143_RAMSIZE 0x70000
53
54/* All D11 cores, ID 0x812 */
55#define BCM43xx_CORE_D11_BASE 0x18001000
56
57#define SBCOREREV(sbidh) \
58 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
59 ((sbidh) & SSB_IDHIGH_RCLO))
60
61/* SOC Interconnect types (aka chip types) */
62#define SOCI_SB 0
63#define SOCI_AI 1
64
65/* EROM CompIdentB */
66#define CIB_REV_MASK 0xff000000
67#define CIB_REV_SHIFT 24
68
69/* ARM CR4 core specific control flag bits */
70#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
71
72/* D11 core specific control flag bits */
73#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
74#define D11_BCMA_IOCTL_PHYRESET 0x0008
75
76#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
77/* SDIO Pad drive strength to select value mappings */
78struct sdiod_drive_str {
79 u8 strength; /* Pad Drive Strength in mA */
80 u8 sel; /* Chip-specific select value */
81};
82/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
83static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
84 {32, 0x6},
85 {26, 0x7},
86 {22, 0x4},
87 {16, 0x5},
88 {12, 0x2},
89 {8, 0x3},
90 {4, 0x0},
91 {0, 0x1}
92};
93
94/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
95static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
96 {6, 0x7},
97 {5, 0x6},
98 {4, 0x5},
99 {3, 0x4},
100 {2, 0x2},
101 {1, 0x1},
102 {0, 0x0}
103};
104
105/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
106static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
107 {3, 0x3},
108 {2, 0x2},
109 {1, 0x1},
110 {0, 0x0} };
111
112/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
113static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
114 {16, 0x7},
115 {12, 0x5},
116 {8, 0x3},
117 {4, 0x1}
118};
119
120u8
121brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid)
122{
123 u8 idx;
124
125 for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
126 if (coreid == ci->c_inf[idx].id)
127 return idx;
128
129 return BRCMF_MAX_CORENUM;
130}
131
132static u32
133brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
134 struct brcmf_chip *ci, u16 coreid)
135{
136 u32 regdata;
137 u8 idx;
138
139 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
140
141 regdata = brcmf_sdiod_regrl(sdiodev,
142 CORE_SB(ci->c_inf[idx].base, sbidhigh),
143 NULL);
144 return SBCOREREV(regdata);
145}
146
147static u32
148brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
149 struct brcmf_chip *ci, u16 coreid)
150{
151 u8 idx;
152
153 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
154
155 return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
156}
157
158static bool
159brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
160 struct brcmf_chip *ci, u16 coreid)
161{
162 u32 regdata;
163 u8 idx;
164
165 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
166 if (idx == BRCMF_MAX_CORENUM)
167 return false;
168
169 regdata = brcmf_sdiod_regrl(sdiodev,
170 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
171 NULL);
172 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
173 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
174 return (SSB_TMSLOW_CLOCK == regdata);
175}
176
177static bool
178brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
179 struct brcmf_chip *ci, u16 coreid)
180{
181 u32 regdata;
182 u8 idx;
183 bool ret;
184
185 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
186 if (idx == BRCMF_MAX_CORENUM)
187 return false;
188
189 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
190 NULL);
191 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
192
193 regdata = brcmf_sdiod_regrl(sdiodev,
194 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
195 NULL);
196 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
197
198 return ret;
199}
200
201static void
202brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
203 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
204 u32 in_resetbits)
205{
206 u32 regdata, base;
207 u8 idx;
208
209 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
210 base = ci->c_inf[idx].base;
211
212 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
213 if (regdata & SSB_TMSLOW_RESET)
214 return;
215
216 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
217 if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
218 /*
219 * set target reject and spin until busy is clear
220 * (preserve core-specific bits)
221 */
222 regdata = brcmf_sdiod_regrl(sdiodev,
223 CORE_SB(base, sbtmstatelow), NULL);
224 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
225 regdata | SSB_TMSLOW_REJECT, NULL);
226
227 regdata = brcmf_sdiod_regrl(sdiodev,
228 CORE_SB(base, sbtmstatelow), NULL);
229 udelay(1);
230 SPINWAIT((brcmf_sdiod_regrl(sdiodev,
231 CORE_SB(base, sbtmstatehigh),
232 NULL) &
233 SSB_TMSHIGH_BUSY), 100000);
234
235 regdata = brcmf_sdiod_regrl(sdiodev,
236 CORE_SB(base, sbtmstatehigh),
237 NULL);
238 if (regdata & SSB_TMSHIGH_BUSY)
239 brcmf_err("core state still busy\n");
240
241 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
242 NULL);
243 if (regdata & SSB_IDLOW_INITIATOR) {
244 regdata = brcmf_sdiod_regrl(sdiodev,
245 CORE_SB(base, sbimstate),
246 NULL);
247 regdata |= SSB_IMSTATE_REJECT;
248 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
249 regdata, NULL);
250 regdata = brcmf_sdiod_regrl(sdiodev,
251 CORE_SB(base, sbimstate),
252 NULL);
253 udelay(1);
254 SPINWAIT((brcmf_sdiod_regrl(sdiodev,
255 CORE_SB(base, sbimstate),
256 NULL) &
257 SSB_IMSTATE_BUSY), 100000);
258 }
259
260 /* set reset and reject while enabling the clocks */
261 regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
262 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
263 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
264 regdata, NULL);
265 regdata = brcmf_sdiod_regrl(sdiodev,
266 CORE_SB(base, sbtmstatelow), NULL);
267 udelay(10);
268
269 /* clear the initiator reject bit */
270 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
271 NULL);
272 if (regdata & SSB_IDLOW_INITIATOR) {
273 regdata = brcmf_sdiod_regrl(sdiodev,
274 CORE_SB(base, sbimstate),
275 NULL);
276 regdata &= ~SSB_IMSTATE_REJECT;
277 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
278 regdata, NULL);
279 }
280 }
281
282 /* leave reset and reject asserted */
283 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
284 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
285 udelay(1);
286}
287
288static void
289brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
290 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
291 u32 in_resetbits)
292{
293 u8 idx;
294 u32 regdata;
295 u32 wrapbase;
296
297 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
298 if (idx == BRCMF_MAX_CORENUM)
299 return;
300
301 wrapbase = ci->c_inf[idx].wrapbase;
302
303 /* if core is already in reset, just return */
304 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
305 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
306 return;
307
308 /* configure reset */
309 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
310 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
311 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
312
313 /* put in reset */
314 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
315 BCMA_RESET_CTL_RESET, NULL);
316 usleep_range(10, 20);
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);
326}
327
328static void
329brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
330 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
331 u32 in_resetbits, u32 post_resetbits)
332{
333 u32 regdata;
334 u8 idx;
335
336 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
337 if (idx == BRCMF_MAX_CORENUM)
338 return;
339
340 /*
341 * Must do the disable sequence first to work for
342 * arbitrary current core state.
343 */
344 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
345 in_resetbits);
346
347 /*
348 * Now do the initialization sequence.
349 * set reset while enabling the clock and
350 * forcing them on throughout the core
351 */
352 brcmf_sdiod_regwl(sdiodev,
353 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
354 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
355 NULL);
356 regdata = brcmf_sdiod_regrl(sdiodev,
357 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
358 NULL);
359 udelay(1);
360
361 /* clear any serror */
362 regdata = brcmf_sdiod_regrl(sdiodev,
363 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
364 NULL);
365 if (regdata & SSB_TMSHIGH_SERR)
366 brcmf_sdiod_regwl(sdiodev,
367 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
368 0, NULL);
369
370 regdata = brcmf_sdiod_regrl(sdiodev,
371 CORE_SB(ci->c_inf[idx].base, sbimstate),
372 NULL);
373 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
374 brcmf_sdiod_regwl(sdiodev,
375 CORE_SB(ci->c_inf[idx].base, sbimstate),
376 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
377 NULL);
378
379 /* clear reset and allow it to propagate throughout the core */
380 brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
381 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
382 regdata = brcmf_sdiod_regrl(sdiodev,
383 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
384 NULL);
385 udelay(1);
386
387 /* leave clock enabled */
388 brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
389 SSB_TMSLOW_CLOCK, NULL);
390 regdata = brcmf_sdiod_regrl(sdiodev,
391 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
392 NULL);
393 udelay(1);
394}
395
396static void
397brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
398 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
399 u32 in_resetbits, u32 post_resetbits)
400{
401 u8 idx;
402 u32 regdata;
403 u32 wrapbase;
404
405 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
406 if (idx == BRCMF_MAX_CORENUM)
407 return;
408
409 wrapbase = ci->c_inf[idx].wrapbase;
410
411 /* must disable first to work for arbitrary current core state */
412 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
413 in_resetbits);
414
415 while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
416 BCMA_RESET_CTL_RESET) {
417 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
418 usleep_range(40, 60);
419 }
420
421 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
422 BCMA_IOCTL_CLK, NULL);
423 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
424}
425
426#ifdef DEBUG
427/* safety check for chipinfo */
428static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
429{
430 u8 core_idx;
431
432 /* check RAM core presence for ARM CM3 core */
433 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
434 if (BRCMF_MAX_CORENUM != core_idx) {
435 core_idx = brcmf_sdio_chip_getinfidx(ci,
436 BCMA_CORE_INTERNAL_MEM);
437 if (BRCMF_MAX_CORENUM == core_idx) {
438 brcmf_err("RAM core not provided with ARM CM3 core\n");
439 return -ENODEV;
440 }
441 }
442
443 /* check RAM base for ARM CR4 core */
444 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
445 if (BRCMF_MAX_CORENUM != core_idx) {
446 if (ci->rambase == 0) {
447 brcmf_err("RAM base not provided with ARM CR4 core\n");
448 return -ENOMEM;
449 }
450 }
451
452 return 0;
453}
454#else /* DEBUG */
455static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
456{
457 return 0;
458}
459#endif
460
461static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
462 struct brcmf_chip *ci)
463{
464 u32 regdata;
465 u32 socitype;
466
467 /* Get CC core rev
468 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
469 * For different chiptypes or old sdio hosts w/o chipcommon,
470 * other ways of recognition should be added here.
471 */
472 regdata = brcmf_sdiod_regrl(sdiodev,
473 CORE_CC_REG(SI_ENUM_BASE, chipid),
474 NULL);
475 ci->chip = regdata & CID_ID_MASK;
476 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
477 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
478 ci->chiprev >= 2)
479 ci->chip = BCM4339_CHIP_ID;
480 socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
481
482 brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n",
483 socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev);
484
485 if (socitype == SOCI_SB) {
486 if (ci->chip != BCM4329_CHIP_ID) {
487 brcmf_err("SB chip is not supported\n");
488 return -ENODEV;
489 }
490 ci->iscoreup = brcmf_sdio_sb_iscoreup;
491 ci->corerev = brcmf_sdio_sb_corerev;
492 ci->coredisable = brcmf_sdio_sb_coredisable;
493 ci->resetcore = brcmf_sdio_sb_resetcore;
494
495 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
496 ci->c_inf[0].base = SI_ENUM_BASE;
497 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
498 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
499 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
500 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
501 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
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;
505 ci->ramsize = BCM4329_RAMSIZE;
506 } else if (socitype == SOCI_AI) {
507 ci->iscoreup = brcmf_sdio_ai_iscoreup;
508 ci->corerev = brcmf_sdio_ai_corerev;
509 ci->coredisable = brcmf_sdio_ai_coredisable;
510 ci->resetcore = brcmf_sdio_ai_resetcore;
511
512 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
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);
658 return -ENODEV;
659 }
660
661 return brcmf_sdio_chip_cichk(ci);
662}
663
664static int
665brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
666{
667 int err = 0;
668 u8 clkval, clkset;
669
670 /* Try forcing SDIO core to do ALPAvail request only */
671 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
672 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
673 if (err) {
674 brcmf_err("error writing for HT off\n");
675 return err;
676 }
677
678 /* If register supported, wait for ALPAvail and then force ALP */
679 /* This may take up to 15 milliseconds */
680 clkval = brcmf_sdiod_regrb(sdiodev,
681 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
682
683 if ((clkval & ~SBSDIO_AVBITS) != clkset) {
684 brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
685 clkset, clkval);
686 return -EACCES;
687 }
688
689 SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
690 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
691 !SBSDIO_ALPAV(clkval)),
692 PMU_MAX_TRANSITION_DLY);
693 if (!SBSDIO_ALPAV(clkval)) {
694 brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
695 clkval);
696 return -EBUSY;
697 }
698
699 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
700 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
701 udelay(65);
702
703 /* Also, disable the extra SDIO pull-ups */
704 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
705
706 return 0;
707}
708
709static void
710brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
711 struct brcmf_chip *ci)
712{
713 u32 base = ci->c_inf[0].base;
714
715 /* get chipcommon rev */
716 ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
717
718 /* get chipcommon capabilites */
719 ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev,
720 CORE_CC_REG(base, capabilities),
721 NULL);
722
723 /* get pmu caps & rev */
724 if (ci->c_inf[0].caps & CC_CAP_PMU) {
725 ci->pmucaps =
726 brcmf_sdiod_regrl(sdiodev,
727 CORE_CC_REG(base, pmucapabilities),
728 NULL);
729 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
730 }
731
732 ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
733
734 brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
735 ci->c_inf[0].rev, ci->pmurev,
736 ci->c_inf[1].rev, ci->c_inf[1].id);
737
738 /*
739 * Make sure any on-chip ARM is off (in case strapping is wrong),
740 * or downloaded code was already running.
741 */
742 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
743}
744
745int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
746 struct brcmf_chip **ci_ptr)
747{
748 int ret;
749 struct brcmf_chip *ci;
750
751 brcmf_dbg(TRACE, "Enter\n");
752
753 ci = kzalloc(sizeof(*ci), GFP_ATOMIC);
754 if (!ci)
755 return -ENOMEM;
756
757 ret = brcmf_sdio_chip_buscoreprep(sdiodev);
758 if (ret != 0)
759 goto err;
760
761 ret = brcmf_sdio_chip_recognition(sdiodev, ci);
762 if (ret != 0)
763 goto err;
764
765 brcmf_sdio_chip_buscoresetup(sdiodev, ci);
766
767 brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
768 0, NULL);
769 brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
770 0, NULL);
771
772 *ci_ptr = ci;
773 return 0;
774
775err:
776 kfree(ci);
777 return ret;
778}
779
780void
781brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr)
782{
783 brcmf_dbg(TRACE, "Enter\n");
784
785 kfree(*ci_ptr);
786 *ci_ptr = NULL;
787}
788
789static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
790{
791 const char *fmt;
792
793 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
794 snprintf(buf, len, fmt, chipid);
795 return buf;
796}
797
798void
799brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
800 struct brcmf_chip *ci, u32 drivestrength)
801{
802 const struct sdiod_drive_str *str_tab = NULL;
803 u32 str_mask;
804 u32 str_shift;
805 char chn[8];
806 u32 base = ci->c_inf[0].base;
807 u32 i;
808 u32 drivestrength_sel = 0;
809 u32 cc_data_temp;
810 u32 addr;
811
812 if (!(ci->c_inf[0].caps & CC_CAP_PMU))
813 return;
814
815 switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
816 case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
817 str_tab = sdiod_drvstr_tab1_1v8;
818 str_mask = 0x00003800;
819 str_shift = 11;
820 break;
821 case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
822 str_tab = sdiod_drvstr_tab6_1v8;
823 str_mask = 0x00001800;
824 str_shift = 11;
825 break;
826 case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
827 /* note: 43143 does not support tristate */
828 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
829 if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
830 str_tab = sdiod_drvstr_tab2_3v3;
831 str_mask = 0x00000007;
832 str_shift = 0;
833 } else
834 brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
835 brcmf_sdio_chip_name(ci->chip, chn, 8),
836 drivestrength);
837 break;
838 case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
839 str_tab = sdiod_drive_strength_tab5_1v8;
840 str_mask = 0x00003800;
841 str_shift = 11;
842 break;
843 default:
844 brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
845 brcmf_sdio_chip_name(ci->chip, chn, 8),
846 ci->chiprev, ci->pmurev);
847 break;
848 }
849
850 if (str_tab != NULL) {
851 for (i = 0; str_tab[i].strength != 0; i++) {
852 if (drivestrength >= str_tab[i].strength) {
853 drivestrength_sel = str_tab[i].sel;
854 break;
855 }
856 }
857 addr = CORE_CC_REG(base, chipcontrol_addr);
858 brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
859 cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
860 cc_data_temp &= ~str_mask;
861 drivestrength_sel <<= str_shift;
862 cc_data_temp |= drivestrength_sel;
863 brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
864
865 brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
866 str_tab[i].strength, drivestrength, cc_data_temp);
867 }
868}
869
870static void
871brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
872 struct brcmf_chip *ci)
873{
874 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
875 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
876 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
877 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
878 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
879}
880
881static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev,
882 struct brcmf_chip *ci)
883{
884 u8 core_idx;
885 u32 reg_addr;
886
887 if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
888 brcmf_err("SOCRAM core is down after reset?\n");
889 return false;
890 }
891
892 /* clear all interrupts */
893 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
894 reg_addr = ci->c_inf[core_idx].base;
895 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
896 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
897
898 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
899
900 return true;
901}
902
903static inline void
904brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
905 struct brcmf_chip *ci)
906{
907 u8 idx;
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);
923}
924
925static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev,
926 struct brcmf_chip *ci, u32 rstvec)
927{
928 u8 core_idx;
929 u32 reg_addr;
930
931 /* clear all interrupts */
932 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
933 reg_addr = ci->c_inf[core_idx].base;
934 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
935 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
936
937 /* Write reset vector to address 0 */
938 brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
939 sizeof(rstvec));
940
941 /* restore ARM */
942 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
943 0, 0);
944
945 return true;
946}
947
948void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
949 struct brcmf_chip *ci)
950{
951 u8 arm_core_idx;
952
953 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
954 if (BRCMF_MAX_CORENUM != arm_core_idx) {
955 brcmf_sdio_chip_cm3_enterdl(sdiodev, ci);
956 return;
957 }
958
959 brcmf_sdio_chip_cr4_enterdl(sdiodev, ci);
960}
961
962bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
963 struct brcmf_chip *ci, u32 rstvec)
964{
965 u8 arm_core_idx;
966
967 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
968 if (BRCMF_MAX_CORENUM != arm_core_idx)
969 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
970
971 return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec);
972}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
deleted file mode 100644
index fb0614329ede..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+++ /dev/null
@@ -1,231 +0,0 @@
1/*
2 * Copyright (c) 2011 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#ifndef _BRCMFMAC_SDIO_CHIP_H_
18#define _BRCMFMAC_SDIO_CHIP_H_
19
20/*
21 * Core reg address translation.
22 * Both macro's returns a 32 bits byte address on the backplane bus.
23 */
24#define CORE_CC_REG(base, field) \
25 (base + offsetof(struct chipcregs, field))
26#define CORE_BUS_REG(base, field) \
27 (base + offsetof(struct sdpcmd_regs, field))
28#define CORE_SB(base, field) \
29 (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
30
31/* SDIO function 1 register CHIPCLKCSR */
32/* Force ALP request to backplane */
33#define SBSDIO_FORCE_ALP 0x01
34/* Force HT request to backplane */
35#define SBSDIO_FORCE_HT 0x02
36/* Force ILP request to backplane */
37#define SBSDIO_FORCE_ILP 0x04
38/* Make ALP ready (power up xtal) */
39#define SBSDIO_ALP_AVAIL_REQ 0x08
40/* Make HT ready (power up PLL) */
41#define SBSDIO_HT_AVAIL_REQ 0x10
42/* Squelch clock requests from HW */
43#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
44/* Status: ALP is ready */
45#define SBSDIO_ALP_AVAIL 0x40
46/* Status: HT is ready */
47#define SBSDIO_HT_AVAIL 0x80
48#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
49#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
50#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
51#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
52#define SBSDIO_CLKAV(regval, alponly) \
53 (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
54
55#define BRCMF_MAX_CORENUM 6
56
57struct brcmf_core {
58 u16 id;
59 u16 rev;
60 u32 base;
61 u32 wrapbase;
62 u32 caps;
63 u32 cib;
64};
65
66struct brcmf_chip {
67 u32 chip;
68 u32 chiprev;
69 /* core info */
70 /* always put chipcommon core at 0, bus core at 1 */
71 struct brcmf_core c_inf[BRCMF_MAX_CORENUM];
72 u32 pmurev;
73 u32 pmucaps;
74 u32 ramsize;
75 u32 rambase;
76 u32 rst_vec; /* reset vertor for ARM CR4 core */
77
78 bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
79 u16 coreid);
80 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
81 u16 coreid);
82 void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
83 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
84 u32 in_resetbits);
85 void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
86 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
87 u32 in_resetbits, u32 post_resetbits);
88};
89
90struct sbconfig {
91 u32 PAD[2];
92 u32 sbipsflag; /* initiator port ocp slave flag */
93 u32 PAD[3];
94 u32 sbtpsflag; /* target port ocp slave flag */
95 u32 PAD[11];
96 u32 sbtmerrloga; /* (sonics >= 2.3) */
97 u32 PAD;
98 u32 sbtmerrlog; /* (sonics >= 2.3) */
99 u32 PAD[3];
100 u32 sbadmatch3; /* address match3 */
101 u32 PAD;
102 u32 sbadmatch2; /* address match2 */
103 u32 PAD;
104 u32 sbadmatch1; /* address match1 */
105 u32 PAD[7];
106 u32 sbimstate; /* initiator agent state */
107 u32 sbintvec; /* interrupt mask */
108 u32 sbtmstatelow; /* target state */
109 u32 sbtmstatehigh; /* target state */
110 u32 sbbwa0; /* bandwidth allocation table0 */
111 u32 PAD;
112 u32 sbimconfiglow; /* initiator configuration */
113 u32 sbimconfighigh; /* initiator configuration */
114 u32 sbadmatch0; /* address match0 */
115 u32 PAD;
116 u32 sbtmconfiglow; /* target configuration */
117 u32 sbtmconfighigh; /* target configuration */
118 u32 sbbconfig; /* broadcast configuration */
119 u32 PAD;
120 u32 sbbstate; /* broadcast state */
121 u32 PAD[3];
122 u32 sbactcnfg; /* activate configuration */
123 u32 PAD[3];
124 u32 sbflagst; /* current sbflags */
125 u32 PAD[3];
126 u32 sbidlow; /* identification */
127 u32 sbidhigh; /* identification */
128};
129
130/* sdio core registers */
131struct sdpcmd_regs {
132 u32 corecontrol; /* 0x00, rev8 */
133 u32 corestatus; /* rev8 */
134 u32 PAD[1];
135 u32 biststatus; /* rev8 */
136
137 /* PCMCIA access */
138 u16 pcmciamesportaladdr; /* 0x010, rev8 */
139 u16 PAD[1];
140 u16 pcmciamesportalmask; /* rev8 */
141 u16 PAD[1];
142 u16 pcmciawrframebc; /* rev8 */
143 u16 PAD[1];
144 u16 pcmciaunderflowtimer; /* rev8 */
145 u16 PAD[1];
146
147 /* interrupt */
148 u32 intstatus; /* 0x020, rev8 */
149 u32 hostintmask; /* rev8 */
150 u32 intmask; /* rev8 */
151 u32 sbintstatus; /* rev8 */
152 u32 sbintmask; /* rev8 */
153 u32 funcintmask; /* rev4 */
154 u32 PAD[2];
155 u32 tosbmailbox; /* 0x040, rev8 */
156 u32 tohostmailbox; /* rev8 */
157 u32 tosbmailboxdata; /* rev8 */
158 u32 tohostmailboxdata; /* rev8 */
159
160 /* synchronized access to registers in SDIO clock domain */
161 u32 sdioaccess; /* 0x050, rev8 */
162 u32 PAD[3];
163
164 /* PCMCIA frame control */
165 u8 pcmciaframectrl; /* 0x060, rev8 */
166 u8 PAD[3];
167 u8 pcmciawatermark; /* rev8 */
168 u8 PAD[155];
169
170 /* interrupt batching control */
171 u32 intrcvlazy; /* 0x100, rev8 */
172 u32 PAD[3];
173
174 /* counters */
175 u32 cmd52rd; /* 0x110, rev8 */
176 u32 cmd52wr; /* rev8 */
177 u32 cmd53rd; /* rev8 */
178 u32 cmd53wr; /* rev8 */
179 u32 abort; /* rev8 */
180 u32 datacrcerror; /* rev8 */
181 u32 rdoutofsync; /* rev8 */
182 u32 wroutofsync; /* rev8 */
183 u32 writebusy; /* rev8 */
184 u32 readwait; /* rev8 */
185 u32 readterm; /* rev8 */
186 u32 writeterm; /* rev8 */
187 u32 PAD[40];
188 u32 clockctlstatus; /* rev8 */
189 u32 PAD[7];
190
191 u32 PAD[128]; /* DMA engines */
192
193 /* SDIO/PCMCIA CIS region */
194 char cis[512]; /* 0x400-0x5ff, rev6 */
195
196 /* PCMCIA function control registers */
197 char pcmciafcr[256]; /* 0x600-6ff, rev6 */
198 u16 PAD[55];
199
200 /* PCMCIA backplane access */
201 u16 backplanecsr; /* 0x76E, rev6 */
202 u16 backplaneaddr0; /* rev6 */
203 u16 backplaneaddr1; /* rev6 */
204 u16 backplaneaddr2; /* rev6 */
205 u16 backplaneaddr3; /* rev6 */
206 u16 backplanedata0; /* rev6 */
207 u16 backplanedata1; /* rev6 */
208 u16 backplanedata2; /* rev6 */
209 u16 backplanedata3; /* rev6 */
210 u16 PAD[31];
211
212 /* sprom "size" & "blank" info */
213 u16 spromstatus; /* 0x7BE, rev2 */
214 u32 PAD[464];
215
216 u16 PAD[0x80];
217};
218
219int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
220 struct brcmf_chip **ci_ptr);
221void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr);
222void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
223 struct brcmf_chip *ci,
224 u32 drivestrength);
225u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid);
226void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
227 struct brcmf_chip *ci);
228bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
229 struct brcmf_chip *ci, u32 rstvec);
230
231#endif /* _BRCMFMAC_SDIO_CHIP_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 092e9c824992..3deab7959a0d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -180,6 +180,97 @@ struct brcmf_sdio_dev {
180 uint max_request_size; 180 uint max_request_size;
181 ushort max_segment_count; 181 ushort max_segment_count;
182 uint max_segment_size; 182 uint max_segment_size;
183 uint txglomsz;
184 struct sg_table sgtable;
185};
186
187/* sdio core registers */
188struct sdpcmd_regs {
189 u32 corecontrol; /* 0x00, rev8 */
190 u32 corestatus; /* rev8 */
191 u32 PAD[1];
192 u32 biststatus; /* rev8 */
193
194 /* PCMCIA access */
195 u16 pcmciamesportaladdr; /* 0x010, rev8 */
196 u16 PAD[1];
197 u16 pcmciamesportalmask; /* rev8 */
198 u16 PAD[1];
199 u16 pcmciawrframebc; /* rev8 */
200 u16 PAD[1];
201 u16 pcmciaunderflowtimer; /* rev8 */
202 u16 PAD[1];
203
204 /* interrupt */
205 u32 intstatus; /* 0x020, rev8 */
206 u32 hostintmask; /* rev8 */
207 u32 intmask; /* rev8 */
208 u32 sbintstatus; /* rev8 */
209 u32 sbintmask; /* rev8 */
210 u32 funcintmask; /* rev4 */
211 u32 PAD[2];
212 u32 tosbmailbox; /* 0x040, rev8 */
213 u32 tohostmailbox; /* rev8 */
214 u32 tosbmailboxdata; /* rev8 */
215 u32 tohostmailboxdata; /* rev8 */
216
217 /* synchronized access to registers in SDIO clock domain */
218 u32 sdioaccess; /* 0x050, rev8 */
219 u32 PAD[3];
220
221 /* PCMCIA frame control */
222 u8 pcmciaframectrl; /* 0x060, rev8 */
223 u8 PAD[3];
224 u8 pcmciawatermark; /* rev8 */
225 u8 PAD[155];
226
227 /* interrupt batching control */
228 u32 intrcvlazy; /* 0x100, rev8 */
229 u32 PAD[3];
230
231 /* counters */
232 u32 cmd52rd; /* 0x110, rev8 */
233 u32 cmd52wr; /* rev8 */
234 u32 cmd53rd; /* rev8 */
235 u32 cmd53wr; /* rev8 */
236 u32 abort; /* rev8 */
237 u32 datacrcerror; /* rev8 */
238 u32 rdoutofsync; /* rev8 */
239 u32 wroutofsync; /* rev8 */
240 u32 writebusy; /* rev8 */
241 u32 readwait; /* rev8 */
242 u32 readterm; /* rev8 */
243 u32 writeterm; /* rev8 */
244 u32 PAD[40];
245 u32 clockctlstatus; /* rev8 */
246 u32 PAD[7];
247
248 u32 PAD[128]; /* DMA engines */
249
250 /* SDIO/PCMCIA CIS region */
251 char cis[512]; /* 0x400-0x5ff, rev6 */
252
253 /* PCMCIA function control registers */
254 char pcmciafcr[256]; /* 0x600-6ff, rev6 */
255 u16 PAD[55];
256
257 /* PCMCIA backplane access */
258 u16 backplanecsr; /* 0x76E, rev6 */
259 u16 backplaneaddr0; /* rev6 */
260 u16 backplaneaddr1; /* rev6 */
261 u16 backplaneaddr2; /* rev6 */
262 u16 backplaneaddr3; /* rev6 */
263 u16 backplanedata0; /* rev6 */
264 u16 backplanedata1; /* rev6 */
265 u16 backplanedata2; /* rev6 */
266 u16 backplanedata3; /* rev6 */
267 u16 PAD[31];
268
269 /* sprom "size" & "blank" info */
270 u16 spromstatus; /* 0x7BE, rev2 */
271 u32 PAD[464];
272
273 u16 PAD[0x80];
183}; 274};
184 275
185/* Register/deregister interrupt handler. */ 276/* Register/deregister interrupt handler. */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index d7718a5fa2f0..e0e649aab8db 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/module.h>
21#include <net/cfg80211.h> 22#include <net/cfg80211.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23 24
@@ -190,6 +191,7 @@ static struct ieee80211_supported_band __wl_band_2ghz = {
190 .n_channels = ARRAY_SIZE(__wl_2ghz_channels), 191 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
191 .bitrates = wl_g_rates, 192 .bitrates = wl_g_rates,
192 .n_bitrates = wl_g_rates_size, 193 .n_bitrates = wl_g_rates_size,
194 .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
193}; 195};
194 196
195static struct ieee80211_supported_band __wl_band_5ghz_a = { 197static struct ieee80211_supported_band __wl_band_5ghz_a = {
@@ -251,6 +253,10 @@ struct parsed_vndr_ies {
251 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT]; 253 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
252}; 254};
253 255
256static int brcmf_roamoff;
257module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
258MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
259
254/* Quarter dBm units to mW 260/* Quarter dBm units to mW
255 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 261 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
256 * Table is offset so the last entry is largest mW value that fits in 262 * Table is offset so the last entry is largest mW value that fits in
@@ -351,13 +357,11 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
351 * triples, returning a pointer to the substring whose first element 357 * triples, returning a pointer to the substring whose first element
352 * matches tag 358 * matches tag
353 */ 359 */
354struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key) 360const struct brcmf_tlv *
361brcmf_parse_tlvs(const void *buf, int buflen, uint key)
355{ 362{
356 struct brcmf_tlv *elt; 363 const struct brcmf_tlv *elt = buf;
357 int totlen; 364 int totlen = buflen;
358
359 elt = (struct brcmf_tlv *)buf;
360 totlen = buflen;
361 365
362 /* find tagged parameter */ 366 /* find tagged parameter */
363 while (totlen >= TLV_HDR_LEN) { 367 while (totlen >= TLV_HDR_LEN) {
@@ -378,8 +382,8 @@ struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
378 * not update the tlvs buffer pointer/length. 382 * not update the tlvs buffer pointer/length.
379 */ 383 */
380static bool 384static bool
381brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, 385brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
382 u8 *oui, u32 oui_len, u8 type) 386 const u8 *oui, u32 oui_len, u8 type)
383{ 387{
384 /* If the contents match the OUI and the type */ 388 /* If the contents match the OUI and the type */
385 if (ie[TLV_LEN_OFF] >= oui_len + 1 && 389 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
@@ -401,12 +405,12 @@ brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
401} 405}
402 406
403static struct brcmf_vs_tlv * 407static struct brcmf_vs_tlv *
404brcmf_find_wpaie(u8 *parse, u32 len) 408brcmf_find_wpaie(const u8 *parse, u32 len)
405{ 409{
406 struct brcmf_tlv *ie; 410 const struct brcmf_tlv *ie;
407 411
408 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) { 412 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
409 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len, 413 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
410 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE)) 414 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
411 return (struct brcmf_vs_tlv *)ie; 415 return (struct brcmf_vs_tlv *)ie;
412 } 416 }
@@ -414,9 +418,9 @@ brcmf_find_wpaie(u8 *parse, u32 len)
414} 418}
415 419
416static struct brcmf_vs_tlv * 420static struct brcmf_vs_tlv *
417brcmf_find_wpsie(u8 *parse, u32 len) 421brcmf_find_wpsie(const u8 *parse, u32 len)
418{ 422{
419 struct brcmf_tlv *ie; 423 const struct brcmf_tlv *ie;
420 424
421 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) { 425 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
422 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len, 426 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
@@ -491,6 +495,19 @@ brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
491 return err; 495 return err;
492} 496}
493 497
498static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
499{
500 enum nl80211_iftype iftype;
501
502 iftype = vif->wdev.iftype;
503 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
504}
505
506static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
507{
508 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
509}
510
494static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, 511static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
495 const char *name, 512 const char *name,
496 enum nl80211_iftype type, 513 enum nl80211_iftype type,
@@ -651,7 +668,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
651 type); 668 type);
652 return -EOPNOTSUPP; 669 return -EOPNOTSUPP;
653 case NL80211_IFTYPE_ADHOC: 670 case NL80211_IFTYPE_ADHOC:
654 vif->mode = WL_MODE_IBSS;
655 infra = 0; 671 infra = 0;
656 break; 672 break;
657 case NL80211_IFTYPE_STATION: 673 case NL80211_IFTYPE_STATION:
@@ -667,12 +683,10 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
667 */ 683 */
668 return 0; 684 return 0;
669 } 685 }
670 vif->mode = WL_MODE_BSS;
671 infra = 1; 686 infra = 1;
672 break; 687 break;
673 case NL80211_IFTYPE_AP: 688 case NL80211_IFTYPE_AP:
674 case NL80211_IFTYPE_P2P_GO: 689 case NL80211_IFTYPE_P2P_GO:
675 vif->mode = WL_MODE_AP;
676 ap = 1; 690 ap = 1;
677 break; 691 break;
678 default: 692 default:
@@ -696,7 +710,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
696 err = -EAGAIN; 710 err = -EAGAIN;
697 goto done; 711 goto done;
698 } 712 }
699 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ? 713 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
700 "Adhoc" : "Infra"); 714 "Adhoc" : "Infra");
701 } 715 }
702 ndev->ieee80211_ptr->iftype = type; 716 ndev->ieee80211_ptr->iftype = type;
@@ -1562,9 +1576,9 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1562 struct ieee80211_channel *chan = sme->channel; 1576 struct ieee80211_channel *chan = sme->channel;
1563 struct brcmf_join_params join_params; 1577 struct brcmf_join_params join_params;
1564 size_t join_params_size; 1578 size_t join_params_size;
1565 struct brcmf_tlv *rsn_ie; 1579 const struct brcmf_tlv *rsn_ie;
1566 struct brcmf_vs_tlv *wpa_ie; 1580 const struct brcmf_vs_tlv *wpa_ie;
1567 void *ie; 1581 const void *ie;
1568 u32 ie_len; 1582 u32 ie_len;
1569 struct brcmf_ext_join_params_le *ext_join_params; 1583 struct brcmf_ext_join_params_le *ext_join_params;
1570 u16 chanspec; 1584 u16 chanspec;
@@ -1591,7 +1605,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1591 ie_len = wpa_ie->len + TLV_HDR_LEN; 1605 ie_len = wpa_ie->len + TLV_HDR_LEN;
1592 } else { 1606 } else {
1593 /* find the RSN_IE */ 1607 /* find the RSN_IE */
1594 rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len, 1608 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1609 sme->ie_len,
1595 WLAN_EID_RSN); 1610 WLAN_EID_RSN);
1596 if (rsn_ie) { 1611 if (rsn_ie) {
1597 ie = rsn_ie; 1612 ie = rsn_ie;
@@ -1678,22 +1693,9 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1678 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len); 1693 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1679 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, 1694 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1680 profile->ssid.SSID_len); 1695 profile->ssid.SSID_len);
1681 /*increase dwell time to receive probe response or detect Beacon 1696
1682 * from target AP at a noisy air only during connect command
1683 */
1684 ext_join_params->scan_le.active_time =
1685 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1686 ext_join_params->scan_le.passive_time =
1687 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1688 /* Set up join scan parameters */ 1697 /* Set up join scan parameters */
1689 ext_join_params->scan_le.scan_type = -1; 1698 ext_join_params->scan_le.scan_type = -1;
1690 /* to sync with presence period of VSDB GO.
1691 * Send probe request more frequently. Probe request will be stopped
1692 * when it gets probe response from target AP/GO.
1693 */
1694 ext_join_params->scan_le.nprobes =
1695 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1696 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1697 ext_join_params->scan_le.home_time = cpu_to_le32(-1); 1699 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1698 1700
1699 if (sme->bssid) 1701 if (sme->bssid)
@@ -1706,6 +1708,25 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1706 1708
1707 ext_join_params->assoc_le.chanspec_list[0] = 1709 ext_join_params->assoc_le.chanspec_list[0] =
1708 cpu_to_le16(chanspec); 1710 cpu_to_le16(chanspec);
1711 /* Increase dwell time to receive probe response or detect
1712 * beacon from target AP at a noisy air only during connect
1713 * command.
1714 */
1715 ext_join_params->scan_le.active_time =
1716 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1717 ext_join_params->scan_le.passive_time =
1718 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1719 /* To sync with presence period of VSDB GO send probe request
1720 * more frequently. Probe request will be stopped when it gets
1721 * probe response from target AP/GO.
1722 */
1723 ext_join_params->scan_le.nprobes =
1724 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1725 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1726 } else {
1727 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1728 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1729 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1709 } 1730 }
1710 1731
1711 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params, 1732 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
@@ -1913,7 +1934,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1913 brcmf_dbg(CONN, "Setting the key index %d\n", key.index); 1934 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1914 memcpy(key.data, params->key, key.len); 1935 memcpy(key.data, params->key, key.len);
1915 1936
1916 if ((ifp->vif->mode != WL_MODE_AP) && 1937 if (!brcmf_is_apmode(ifp->vif) &&
1917 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { 1938 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1918 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); 1939 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1919 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 1940 memcpy(keybuf, &key.data[24], sizeof(keybuf));
@@ -1981,7 +2002,9 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1981 if (!check_vif_up(ifp->vif)) 2002 if (!check_vif_up(ifp->vif))
1982 return -EIO; 2003 return -EIO;
1983 2004
1984 if (mac_addr) { 2005 if (mac_addr &&
2006 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2007 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
1985 brcmf_dbg(TRACE, "Exit"); 2008 brcmf_dbg(TRACE, "Exit");
1986 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params); 2009 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1987 } 2010 }
@@ -2010,7 +2033,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2010 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); 2033 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2011 break; 2034 break;
2012 case WLAN_CIPHER_SUITE_TKIP: 2035 case WLAN_CIPHER_SUITE_TKIP:
2013 if (ifp->vif->mode != WL_MODE_AP) { 2036 if (!brcmf_is_apmode(ifp->vif)) {
2014 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); 2037 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2015 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2038 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2016 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 2039 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
@@ -2164,12 +2187,14 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2164 s32 err = 0; 2187 s32 err = 0;
2165 u8 *bssid = profile->bssid; 2188 u8 *bssid = profile->bssid;
2166 struct brcmf_sta_info_le sta_info_le; 2189 struct brcmf_sta_info_le sta_info_le;
2190 u32 beacon_period;
2191 u32 dtim_period;
2167 2192
2168 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac); 2193 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2169 if (!check_vif_up(ifp->vif)) 2194 if (!check_vif_up(ifp->vif))
2170 return -EIO; 2195 return -EIO;
2171 2196
2172 if (ifp->vif->mode == WL_MODE_AP) { 2197 if (brcmf_is_apmode(ifp->vif)) {
2173 memcpy(&sta_info_le, mac, ETH_ALEN); 2198 memcpy(&sta_info_le, mac, ETH_ALEN);
2174 err = brcmf_fil_iovar_data_get(ifp, "sta_info", 2199 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2175 &sta_info_le, 2200 &sta_info_le,
@@ -2186,7 +2211,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2186 } 2211 }
2187 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", 2212 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2188 sinfo->inactive_time, sinfo->connected_time); 2213 sinfo->inactive_time, sinfo->connected_time);
2189 } else if (ifp->vif->mode == WL_MODE_BSS) { 2214 } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
2190 if (memcmp(mac, bssid, ETH_ALEN)) { 2215 if (memcmp(mac, bssid, ETH_ALEN)) {
2191 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", 2216 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2192 mac, bssid); 2217 mac, bssid);
@@ -2218,6 +2243,30 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2218 sinfo->signal = rssi; 2243 sinfo->signal = rssi;
2219 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); 2244 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2220 } 2245 }
2246 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
2247 &beacon_period);
2248 if (err) {
2249 brcmf_err("Could not get beacon period (%d)\n",
2250 err);
2251 goto done;
2252 } else {
2253 sinfo->bss_param.beacon_interval =
2254 beacon_period;
2255 brcmf_dbg(CONN, "Beacon peroid %d\n",
2256 beacon_period);
2257 }
2258 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
2259 &dtim_period);
2260 if (err) {
2261 brcmf_err("Could not get DTIM period (%d)\n",
2262 err);
2263 goto done;
2264 } else {
2265 sinfo->bss_param.dtim_period = dtim_period;
2266 brcmf_dbg(CONN, "DTIM peroid %d\n",
2267 dtim_period);
2268 }
2269 sinfo->filled |= STATION_INFO_BSS_PARAM;
2221 } 2270 }
2222 } else 2271 } else
2223 err = -EPERM; 2272 err = -EPERM;
@@ -2444,18 +2493,13 @@ CleanUp:
2444 return err; 2493 return err;
2445} 2494}
2446 2495
2447static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2448{
2449 return vif->mode == WL_MODE_IBSS;
2450}
2451
2452static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg, 2496static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2453 struct brcmf_if *ifp) 2497 struct brcmf_if *ifp)
2454{ 2498{
2455 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev); 2499 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2456 struct brcmf_bss_info_le *bi; 2500 struct brcmf_bss_info_le *bi;
2457 struct brcmf_ssid *ssid; 2501 struct brcmf_ssid *ssid;
2458 struct brcmf_tlv *tim; 2502 const struct brcmf_tlv *tim;
2459 u16 beacon_interval; 2503 u16 beacon_interval;
2460 u8 dtim_period; 2504 u8 dtim_period;
2461 size_t ie_len; 2505 size_t ie_len;
@@ -3220,8 +3264,9 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3220} 3264}
3221 3265
3222static s32 3266static s32
3223brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, 3267brcmf_configure_wpaie(struct net_device *ndev,
3224 bool is_rsn_ie) 3268 const struct brcmf_vs_tlv *wpa_ie,
3269 bool is_rsn_ie)
3225{ 3270{
3226 struct brcmf_if *ifp = netdev_priv(ndev); 3271 struct brcmf_if *ifp = netdev_priv(ndev);
3227 u32 auth = 0; /* d11 open authentication */ 3272 u32 auth = 0; /* d11 open authentication */
@@ -3707,11 +3752,11 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3707 s32 ie_offset; 3752 s32 ie_offset;
3708 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3753 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3709 struct brcmf_if *ifp = netdev_priv(ndev); 3754 struct brcmf_if *ifp = netdev_priv(ndev);
3710 struct brcmf_tlv *ssid_ie; 3755 const struct brcmf_tlv *ssid_ie;
3711 struct brcmf_ssid_le ssid_le; 3756 struct brcmf_ssid_le ssid_le;
3712 s32 err = -EPERM; 3757 s32 err = -EPERM;
3713 struct brcmf_tlv *rsn_ie; 3758 const struct brcmf_tlv *rsn_ie;
3714 struct brcmf_vs_tlv *wpa_ie; 3759 const struct brcmf_vs_tlv *wpa_ie;
3715 struct brcmf_join_params join_params; 3760 struct brcmf_join_params join_params;
3716 enum nl80211_iftype dev_role; 3761 enum nl80211_iftype dev_role;
3717 struct brcmf_fil_bss_enable_le bss_enable; 3762 struct brcmf_fil_bss_enable_le bss_enable;
@@ -4220,32 +4265,6 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4220 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode) 4265 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4221}; 4266};
4222 4267
4223static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4224{
4225 switch (type) {
4226 case NL80211_IFTYPE_AP_VLAN:
4227 case NL80211_IFTYPE_WDS:
4228 case NL80211_IFTYPE_MONITOR:
4229 case NL80211_IFTYPE_MESH_POINT:
4230 return -ENOTSUPP;
4231 case NL80211_IFTYPE_ADHOC:
4232 return WL_MODE_IBSS;
4233 case NL80211_IFTYPE_STATION:
4234 case NL80211_IFTYPE_P2P_CLIENT:
4235 return WL_MODE_BSS;
4236 case NL80211_IFTYPE_AP:
4237 case NL80211_IFTYPE_P2P_GO:
4238 return WL_MODE_AP;
4239 case NL80211_IFTYPE_P2P_DEVICE:
4240 return WL_MODE_P2P;
4241 case NL80211_IFTYPE_UNSPECIFIED:
4242 default:
4243 break;
4244 }
4245
4246 return -EINVAL;
4247}
4248
4249static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 4268static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4250{ 4269{
4251 /* scheduled scan settings */ 4270 /* scheduled scan settings */
@@ -4370,7 +4389,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4370 vif->wdev.wiphy = cfg->wiphy; 4389 vif->wdev.wiphy = cfg->wiphy;
4371 vif->wdev.iftype = type; 4390 vif->wdev.iftype = type;
4372 4391
4373 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4374 vif->pm_block = pm_block; 4392 vif->pm_block = pm_block;
4375 vif->roam_off = -1; 4393 vif->roam_off = -1;
4376 4394
@@ -4416,7 +4434,9 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4416 u32 event = e->event_code; 4434 u32 event = e->event_code;
4417 u16 flags = e->flags; 4435 u16 flags = e->flags;
4418 4436
4419 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { 4437 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4438 (event == BRCMF_E_DISASSOC_IND) ||
4439 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4420 brcmf_dbg(CONN, "Processing link down\n"); 4440 brcmf_dbg(CONN, "Processing link down\n");
4421 return true; 4441 return true;
4422 } 4442 }
@@ -4658,16 +4678,19 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4658 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 4678 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4659 struct net_device *ndev = ifp->ndev; 4679 struct net_device *ndev = ifp->ndev;
4660 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4680 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4681 struct ieee80211_channel *chan;
4661 s32 err = 0; 4682 s32 err = 0;
4683 u16 reason;
4662 4684
4663 if (ifp->vif->mode == WL_MODE_AP) { 4685 if (brcmf_is_apmode(ifp->vif)) {
4664 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); 4686 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4665 } else if (brcmf_is_linkup(e)) { 4687 } else if (brcmf_is_linkup(e)) {
4666 brcmf_dbg(CONN, "Linkup\n"); 4688 brcmf_dbg(CONN, "Linkup\n");
4667 if (brcmf_is_ibssmode(ifp->vif)) { 4689 if (brcmf_is_ibssmode(ifp->vif)) {
4690 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4668 memcpy(profile->bssid, e->addr, ETH_ALEN); 4691 memcpy(profile->bssid, e->addr, ETH_ALEN);
4669 wl_inform_ibss(cfg, ndev, e->addr); 4692 wl_inform_ibss(cfg, ndev, e->addr);
4670 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); 4693 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4671 clear_bit(BRCMF_VIF_STATUS_CONNECTING, 4694 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4672 &ifp->vif->sme_state); 4695 &ifp->vif->sme_state);
4673 set_bit(BRCMF_VIF_STATUS_CONNECTED, 4696 set_bit(BRCMF_VIF_STATUS_CONNECTED,
@@ -4679,9 +4702,15 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4679 if (!brcmf_is_ibssmode(ifp->vif)) { 4702 if (!brcmf_is_ibssmode(ifp->vif)) {
4680 brcmf_bss_connect_done(cfg, ndev, e, false); 4703 brcmf_bss_connect_done(cfg, ndev, e, false);
4681 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, 4704 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4682 &ifp->vif->sme_state)) 4705 &ifp->vif->sme_state)) {
4683 cfg80211_disconnected(ndev, 0, NULL, 0, 4706 reason = 0;
4707 if (((e->event_code == BRCMF_E_DEAUTH_IND) ||
4708 (e->event_code == BRCMF_E_DISASSOC_IND)) &&
4709 (e->reason != WLAN_REASON_UNSPECIFIED))
4710 reason = e->reason;
4711 cfg80211_disconnected(ndev, reason, NULL, 0,
4684 GFP_KERNEL); 4712 GFP_KERNEL);
4713 }
4685 } 4714 }
4686 brcmf_link_down(ifp->vif); 4715 brcmf_link_down(ifp->vif);
4687 brcmf_init_prof(ndev_to_prof(ndev)); 4716 brcmf_init_prof(ndev_to_prof(ndev));
@@ -4875,11 +4904,8 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4875 4904
4876 cfg->scan_request = NULL; 4905 cfg->scan_request = NULL;
4877 cfg->pwr_save = true; 4906 cfg->pwr_save = true;
4878 cfg->roam_on = true; /* roam on & off switch. 4907 cfg->active_scan = true; /* we do active scan per default */
4879 we enable roam per default */ 4908 cfg->dongle_up = false; /* dongle is not up yet */
4880 cfg->active_scan = true; /* we do active scan for
4881 specific scan per default */
4882 cfg->dongle_up = false; /* dongle is not up yet */
4883 err = brcmf_init_priv_mem(cfg); 4909 err = brcmf_init_priv_mem(cfg);
4884 if (err) 4910 if (err)
4885 return err; 4911 return err;
@@ -4904,6 +4930,30 @@ static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4904 mutex_init(&event->vif_event_lock); 4930 mutex_init(&event->vif_event_lock);
4905} 4931}
4906 4932
4933static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
4934{
4935 struct brcmf_fil_bwcap_le band_bwcap;
4936 u32 val;
4937 int err;
4938
4939 /* verify support for bw_cap command */
4940 val = WLC_BAND_5G;
4941 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
4942
4943 if (!err) {
4944 /* only set 2G bandwidth using bw_cap command */
4945 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
4946 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_40MHZ_BIT);
4947 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
4948 sizeof(band_bwcap));
4949 } else {
4950 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
4951 val = WLC_N_BW_40ALL;
4952 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
4953 }
4954 return err;
4955}
4956
4907struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, 4957struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4908 struct device *busdev) 4958 struct device *busdev)
4909{ 4959{
@@ -4961,6 +5011,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4961 goto cfg80211_p2p_attach_out; 5011 goto cfg80211_p2p_attach_out;
4962 } 5012 }
4963 5013
5014 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5015 * setup 40MHz in 2GHz band and enable OBSS scanning.
5016 */
5017 if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
5018 IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
5019 err = brcmf_enable_bw40_2g(ifp);
5020 if (!err)
5021 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5022 BRCMF_OBSS_COEX_AUTO);
5023 }
5024
4964 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); 5025 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
4965 if (err) { 5026 if (err) {
4966 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); 5027 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
@@ -4999,7 +5060,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4999} 5060}
5000 5061
5001static s32 5062static s32
5002brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout) 5063brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5003{ 5064{
5004 s32 err = 0; 5065 s32 err = 0;
5005 __le32 roamtrigger[2]; 5066 __le32 roamtrigger[2];
@@ -5009,7 +5070,7 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5009 * Setup timeout if Beacons are lost and roam is 5070 * Setup timeout if Beacons are lost and roam is
5010 * off to report link down 5071 * off to report link down
5011 */ 5072 */
5012 if (roamvar) { 5073 if (brcmf_roamoff) {
5013 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); 5074 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5014 if (err) { 5075 if (err) {
5015 brcmf_err("bcn_timeout error (%d)\n", err); 5076 brcmf_err("bcn_timeout error (%d)\n", err);
@@ -5021,8 +5082,9 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5021 * Enable/Disable built-in roaming to allow supplicant 5082 * Enable/Disable built-in roaming to allow supplicant
5022 * to take care of roaming 5083 * to take care of roaming
5023 */ 5084 */
5024 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On"); 5085 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5025 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar); 5086 brcmf_roamoff ? "Off" : "On");
5087 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5026 if (err) { 5088 if (err) {
5027 brcmf_err("roam_off error (%d)\n", err); 5089 brcmf_err("roam_off error (%d)\n", err);
5028 goto dongle_rom_out; 5090 goto dongle_rom_out;
@@ -5164,9 +5226,6 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5164 ieee80211_channel_to_frequency(ch.chnum, band); 5226 ieee80211_channel_to_frequency(ch.chnum, band);
5165 band_chan_arr[index].hw_value = ch.chnum; 5227 band_chan_arr[index].hw_value = ch.chnum;
5166 5228
5167 brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
5168 ch.chnum, band_chan_arr[index].center_freq,
5169 ch.bw, ch.sb);
5170 if (ch.bw == BRCMU_CHAN_BW_40) { 5229 if (ch.bw == BRCMU_CHAN_BW_40) {
5171 /* assuming the order is HT20, HT40 Upper, 5230 /* assuming the order is HT20, HT40 Upper,
5172 * HT40 lower from chanspecs 5231 * HT40 lower from chanspecs
@@ -5267,6 +5326,8 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5267 u32 band_list[3]; 5326 u32 band_list[3];
5268 u32 nmode; 5327 u32 nmode;
5269 u32 bw_cap[2] = { 0, 0 }; 5328 u32 bw_cap[2] = { 0, 0 };
5329 u32 rxchain;
5330 u32 nchain;
5270 s8 phy; 5331 s8 phy;
5271 s32 err; 5332 s32 err;
5272 u32 nband; 5333 u32 nband;
@@ -5303,6 +5364,16 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5303 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, 5364 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5304 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); 5365 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5305 5366
5367 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5368 if (err) {
5369 brcmf_err("rxchain error (%d)\n", err);
5370 nchain = 1;
5371 } else {
5372 for (nchain = 0; rxchain; nchain++)
5373 rxchain = rxchain & (rxchain - 1);
5374 }
5375 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5376
5306 err = brcmf_construct_reginfo(cfg, bw_cap); 5377 err = brcmf_construct_reginfo(cfg, bw_cap);
5307 if (err) { 5378 if (err) {
5308 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err); 5379 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
@@ -5331,10 +5402,7 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5331 band->ht_cap.ht_supported = true; 5402 band->ht_cap.ht_supported = true;
5332 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 5403 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5333 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; 5404 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5334 /* An HT shall support all EQM rates for one spatial 5405 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5335 * stream
5336 */
5337 band->ht_cap.mcs.rx_mask[0] = 0xff;
5338 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 5406 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5339 bands[band->band] = band; 5407 bands[band->band] = band;
5340 } 5408 }
@@ -5381,7 +5449,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5381 brcmf_dbg(INFO, "power save set to %s\n", 5449 brcmf_dbg(INFO, "power save set to %s\n",
5382 (power_mode ? "enabled" : "disabled")); 5450 (power_mode ? "enabled" : "disabled"));
5383 5451
5384 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); 5452 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5385 if (err) 5453 if (err)
5386 goto default_conf_out; 5454 goto default_conf_out;
5387 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, 5455 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 2dc6a074e8ed..283c525a44f7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -89,21 +89,6 @@ enum brcmf_scan_status {
89 BRCMF_SCAN_STATUS_SUPPRESS, 89 BRCMF_SCAN_STATUS_SUPPRESS,
90}; 90};
91 91
92/**
93 * enum wl_mode - driver mode of virtual interface.
94 *
95 * @WL_MODE_BSS: connects to BSS.
96 * @WL_MODE_IBSS: operate as ad-hoc.
97 * @WL_MODE_AP: operate as access-point.
98 * @WL_MODE_P2P: provide P2P discovery.
99 */
100enum wl_mode {
101 WL_MODE_BSS,
102 WL_MODE_IBSS,
103 WL_MODE_AP,
104 WL_MODE_P2P
105};
106
107/* dongle configuration */ 92/* dongle configuration */
108struct brcmf_cfg80211_conf { 93struct brcmf_cfg80211_conf {
109 u32 frag_threshold; 94 u32 frag_threshold;
@@ -193,7 +178,6 @@ struct vif_saved_ie {
193 * @ifp: lower layer interface pointer 178 * @ifp: lower layer interface pointer
194 * @wdev: wireless device. 179 * @wdev: wireless device.
195 * @profile: profile information. 180 * @profile: profile information.
196 * @mode: operating mode.
197 * @roam_off: roaming state. 181 * @roam_off: roaming state.
198 * @sme_state: SME state using enum brcmf_vif_status bits. 182 * @sme_state: SME state using enum brcmf_vif_status bits.
199 * @pm_block: power-management blocked. 183 * @pm_block: power-management blocked.
@@ -204,7 +188,6 @@ struct brcmf_cfg80211_vif {
204 struct brcmf_if *ifp; 188 struct brcmf_if *ifp;
205 struct wireless_dev wdev; 189 struct wireless_dev wdev;
206 struct brcmf_cfg80211_profile profile; 190 struct brcmf_cfg80211_profile profile;
207 s32 mode;
208 s32 roam_off; 191 s32 roam_off;
209 unsigned long sme_state; 192 unsigned long sme_state;
210 bool pm_block; 193 bool pm_block;
@@ -402,7 +385,6 @@ struct brcmf_cfg80211_info {
402 bool ibss_starter; 385 bool ibss_starter;
403 bool pwr_save; 386 bool pwr_save;
404 bool dongle_up; 387 bool dongle_up;
405 bool roam_on;
406 bool scan_tried; 388 bool scan_tried;
407 u8 *dcmd_buf; 389 u8 *dcmd_buf;
408 u8 *extra_buf; 390 u8 *extra_buf;
@@ -491,7 +473,8 @@ void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
491s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, 473s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
492 const u8 *vndr_ie_buf, u32 vndr_ie_len); 474 const u8 *vndr_ie_buf, u32 vndr_ie_len);
493s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif); 475s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
494struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key); 476const struct brcmf_tlv *
477brcmf_parse_tlvs(const void *buf, int buflen, uint key);
495u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, 478u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
496 struct ieee80211_channel *ch); 479 struct ieee80211_channel *ch);
497u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state); 480u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 925034b80e9c..8c5fa4e58139 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -426,6 +426,12 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
426 bool blocked; 426 bool blocked;
427 int err; 427 int err;
428 428
429 if (!wl->ucode.bcm43xx_bomminor) {
430 err = brcms_request_fw(wl, wl->wlc->hw->d11core);
431 if (err)
432 return -ENOENT;
433 }
434
429 ieee80211_wake_queues(hw); 435 ieee80211_wake_queues(hw);
430 spin_lock_bh(&wl->lock); 436 spin_lock_bh(&wl->lock);
431 blocked = brcms_rfkill_set_hw_state(wl); 437 blocked = brcms_rfkill_set_hw_state(wl);
@@ -433,14 +439,6 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
433 if (!blocked) 439 if (!blocked)
434 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); 440 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
435 441
436 if (!wl->ucode.bcm43xx_bomminor) {
437 err = brcms_request_fw(wl, wl->wlc->hw->d11core);
438 if (err) {
439 brcms_remove(wl->wlc->hw->d11core);
440 return -ENOENT;
441 }
442 }
443
444 spin_lock_bh(&wl->lock); 442 spin_lock_bh(&wl->lock);
445 /* avoid acknowledging frames before a non-monitor device is added */ 443 /* avoid acknowledging frames before a non-monitor device is added */
446 wl->mute_tx = true; 444 wl->mute_tx = true;
@@ -1094,12 +1092,6 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
1094 * Attach to the WL device identified by vendor and device parameters. 1092 * Attach to the WL device identified by vendor and device parameters.
1095 * regs is a host accessible memory address pointing to WL device registers. 1093 * regs is a host accessible memory address pointing to WL device registers.
1096 * 1094 *
1097 * brcms_attach is not defined as static because in the case where no bus
1098 * is defined, wl_attach will never be called, and thus, gcc will issue
1099 * a warning that this function is defined but not used if we declare
1100 * it as static.
1101 *
1102 *
1103 * is called in brcms_bcma_probe() context, therefore no locking required. 1095 * is called in brcms_bcma_probe() context, therefore no locking required.
1104 */ 1096 */
1105static struct brcms_info *brcms_attach(struct bcma_device *pdev) 1097static struct brcms_info *brcms_attach(struct bcma_device *pdev)
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index 6fa5d4863782..d816270db3be 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -43,5 +43,6 @@
43#define BCM4335_CHIP_ID 0x4335 43#define BCM4335_CHIP_ID 0x4335
44#define BCM43362_CHIP_ID 43362 44#define BCM43362_CHIP_ID 43362
45#define BCM4339_CHIP_ID 0x4339 45#define BCM4339_CHIP_ID 0x4339
46#define BCM4354_CHIP_ID 0x4354
46 47
47#endif /* _BRCM_HW_IDS_H_ */ 48#endif /* _BRCM_HW_IDS_H_ */