aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c28
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c196
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h74
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c274
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.c136
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.h86
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c100
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c49
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c958
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c37
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h60
18 files changed, 1124 insertions, 930 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 4cffb2ee3673..de0cff3df389 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -34,6 +34,7 @@ brcmfmac-objs += \
34 dhd_common.o \ 34 dhd_common.o \
35 dhd_linux.o \ 35 dhd_linux.o \
36 firmware.o \ 36 firmware.o \
37 feature.o \
37 btcoex.o \ 38 btcoex.o \
38 vendor.o 39 vendor.o
39brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ 40brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index a16e644e7c08..f467cafe3e8f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -25,7 +25,6 @@
25#include <linux/mmc/sdio.h> 25#include <linux/mmc/sdio.h>
26#include <linux/mmc/core.h> 26#include <linux/mmc/core.h>
27#include <linux/mmc/sdio_func.h> 27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/sdio_ids.h>
29#include <linux/mmc/card.h> 28#include <linux/mmc/card.h>
30#include <linux/mmc/host.h> 29#include <linux/mmc/host.h>
31#include <linux/platform_device.h> 30#include <linux/platform_device.h>
@@ -979,18 +978,20 @@ out:
979 return ret; 978 return ret;
980} 979}
981 980
981#define BRCMF_SDIO_DEVICE(dev_id) \
982 {SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)}
983
982/* devices we support, null terminated */ 984/* devices we support, null terminated */
983static const struct sdio_device_id brcmf_sdmmc_ids[] = { 985static const struct sdio_device_id brcmf_sdmmc_ids[] = {
984 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, 986 BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID),
985 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, 987 BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID),
986 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, 988 BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID),
987 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, 989 BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID),
988 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, 990 BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID),
989 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)}, 991 BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID),
990 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, 992 BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID),
991 SDIO_DEVICE_ID_BROADCOM_4335_4339)}, 993 BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID),
992 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)}, 994 { /* end: all zeroes */ }
993 { /* end: all zeroes */ },
994}; 995};
995MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); 996MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
996 997
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index c7c9f15c0fe0..96800db0536b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -482,30 +482,30 @@ static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
482static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) 482static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
483{ 483{
484 switch (ci->pub.chip) { 484 switch (ci->pub.chip) {
485 case BCM4329_CHIP_ID: 485 case BRCM_CC_4329_CHIP_ID:
486 ci->pub.ramsize = BCM4329_RAMSIZE; 486 ci->pub.ramsize = BCM4329_RAMSIZE;
487 break; 487 break;
488 case BCM43143_CHIP_ID: 488 case BRCM_CC_43143_CHIP_ID:
489 ci->pub.ramsize = BCM43143_RAMSIZE; 489 ci->pub.ramsize = BCM43143_RAMSIZE;
490 break; 490 break;
491 case BCM43241_CHIP_ID: 491 case BRCM_CC_43241_CHIP_ID:
492 ci->pub.ramsize = 0x90000; 492 ci->pub.ramsize = 0x90000;
493 break; 493 break;
494 case BCM4330_CHIP_ID: 494 case BRCM_CC_4330_CHIP_ID:
495 ci->pub.ramsize = 0x48000; 495 ci->pub.ramsize = 0x48000;
496 break; 496 break;
497 case BCM4334_CHIP_ID: 497 case BRCM_CC_4334_CHIP_ID:
498 ci->pub.ramsize = 0x80000; 498 ci->pub.ramsize = 0x80000;
499 break; 499 break;
500 case BCM4335_CHIP_ID: 500 case BRCM_CC_4335_CHIP_ID:
501 ci->pub.ramsize = 0xc0000; 501 ci->pub.ramsize = 0xc0000;
502 ci->pub.rambase = 0x180000; 502 ci->pub.rambase = 0x180000;
503 break; 503 break;
504 case BCM43362_CHIP_ID: 504 case BRCM_CC_43362_CHIP_ID:
505 ci->pub.ramsize = 0x3c000; 505 ci->pub.ramsize = 0x3c000;
506 break; 506 break;
507 case BCM4339_CHIP_ID: 507 case BRCM_CC_4339_CHIP_ID:
508 case BCM4354_CHIP_ID: 508 case BRCM_CC_4354_CHIP_ID:
509 ci->pub.ramsize = 0xc0000; 509 ci->pub.ramsize = 0xc0000;
510 ci->pub.rambase = 0x180000; 510 ci->pub.rambase = 0x180000;
511 break; 511 break;
@@ -682,7 +682,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
682 ci->pub.chiprev); 682 ci->pub.chiprev);
683 683
684 if (socitype == SOCI_SB) { 684 if (socitype == SOCI_SB) {
685 if (ci->pub.chip != BCM4329_CHIP_ID) { 685 if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
686 brcmf_err("SB chip is not supported\n"); 686 brcmf_err("SB chip is not supported\n");
687 return -ENODEV; 687 return -ENODEV;
688 } 688 }
@@ -1008,13 +1008,13 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
1008 chip = container_of(pub, struct brcmf_chip_priv, pub); 1008 chip = container_of(pub, struct brcmf_chip_priv, pub);
1009 1009
1010 switch (pub->chip) { 1010 switch (pub->chip) {
1011 case BCM4354_CHIP_ID: 1011 case BRCM_CC_4354_CHIP_ID:
1012 /* explicitly check SR engine enable bit */ 1012 /* explicitly check SR engine enable bit */
1013 pmu_cc3_mask = BIT(2); 1013 pmu_cc3_mask = BIT(2);
1014 /* fall-through */ 1014 /* fall-through */
1015 case BCM43241_CHIP_ID: 1015 case BRCM_CC_43241_CHIP_ID:
1016 case BCM4335_CHIP_ID: 1016 case BRCM_CC_4335_CHIP_ID:
1017 case BCM4339_CHIP_ID: 1017 case BRCM_CC_4339_CHIP_ID:
1018 /* read PMU chipcontrol register 3 */ 1018 /* read PMU chipcontrol register 3 */
1019 addr = CORE_CC_REG(base, chipcontrol_addr); 1019 addr = CORE_CC_REG(base, chipcontrol_addr);
1020 chip->ops->write32(chip->ctx, addr, 3); 1020 chip->ops->write32(chip->ctx, addr, 3);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index a8998eb60d22..7da6441bcfa8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -103,6 +103,10 @@ struct brcmf_pub {
103 103
104 struct brcmf_ampdu_rx_reorder 104 struct brcmf_ampdu_rx_reorder
105 *reorder_flows[BRCMF_AMPDU_RX_REORDER_MAXFLOWS]; 105 *reorder_flows[BRCMF_AMPDU_RX_REORDER_MAXFLOWS];
106
107 u32 feat_flags;
108 u32 chip_quirks;
109
106#ifdef DEBUG 110#ifdef DEBUG
107 struct dentry *dbgfs_dir; 111 struct dentry *dbgfs_dir;
108#endif 112#endif
@@ -175,7 +179,6 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
175void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); 179void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
176void brcmf_txflowblock_if(struct brcmf_if *ifp, 180void brcmf_txflowblock_if(struct brcmf_if *ifp,
177 enum brcmf_netif_stop_reason reason, bool state); 181 enum brcmf_netif_stop_reason reason, bool state);
178u32 brcmf_get_chip_info(struct brcmf_if *ifp);
179void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, 182void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
180 bool success); 183 bool success);
181 184
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 03fe8aca4d32..be9f4f829192 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -41,37 +41,12 @@ void brcmf_debugfs_exit(void)
41 root_folder = NULL; 41 root_folder = NULL;
42} 42}
43 43
44static 44static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
45ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
46 size_t count, loff_t *ppos)
47{ 45{
48 struct brcmf_pub *drvr = f->private_data; 46 struct brcmf_bus *bus = dev_get_drvdata(seq->private);
49 struct brcmf_bus *bus = drvr->bus_if;
50 char buf[40];
51 int res;
52
53 /* only allow read from start */
54 if (*ppos > 0)
55 return 0;
56
57 res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
58 bus->chip, bus->chip, bus->chiprev);
59 return simple_read_from_buffer(data, count, ppos, buf, res);
60}
61
62static const struct file_operations brcmf_debugfs_chipinfo_ops = {
63 .owner = THIS_MODULE,
64 .open = simple_open,
65 .read = brcmf_debugfs_chipinfo_read
66};
67
68static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
69{
70 struct dentry *dentry = drvr->dbgfs_dir;
71 47
72 if (!IS_ERR_OR_NULL(dentry)) 48 seq_printf(seq, "chip: %x(%u) rev %u\n",
73 debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr, 49 bus->chip, bus->chip, bus->chiprev);
74 &brcmf_debugfs_chipinfo_ops);
75 return 0; 50 return 0;
76} 51}
77 52
@@ -83,7 +58,8 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
83 return -ENODEV; 58 return -ENODEV;
84 59
85 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); 60 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
86 brcmf_debugfs_create_chipinfo(drvr); 61 brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
62
87 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); 63 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
88} 64}
89 65
@@ -98,148 +74,44 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
98 return drvr->dbgfs_dir; 74 return drvr->dbgfs_dir;
99} 75}
100 76
101static 77struct brcmf_debugfs_entry {
102ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data, 78 int (*read)(struct seq_file *seq, void *data);
103 size_t count, loff_t *ppos) 79 struct brcmf_pub *drvr;
104{
105 struct brcmf_sdio_count *sdcnt = f->private_data;
106 char buf[750];
107 int res;
108
109 /* only allow read from start */
110 if (*ppos > 0)
111 return 0;
112
113 res = scnprintf(buf, sizeof(buf),
114 "intrcount: %u\nlastintrs: %u\n"
115 "pollcnt: %u\nregfails: %u\n"
116 "tx_sderrs: %u\nfcqueued: %u\n"
117 "rxrtx: %u\nrx_toolong: %u\n"
118 "rxc_errors: %u\nrx_hdrfail: %u\n"
119 "rx_badhdr: %u\nrx_badseq: %u\n"
120 "fc_rcvd: %u\nfc_xoff: %u\n"
121 "fc_xon: %u\nrxglomfail: %u\n"
122 "rxglomframes: %u\nrxglompkts: %u\n"
123 "f2rxhdrs: %u\nf2rxdata: %u\n"
124 "f2txdata: %u\nf1regdata: %u\n"
125 "tickcnt: %u\ntx_ctlerrs: %lu\n"
126 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
127 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
128 sdcnt->intrcount, sdcnt->lastintrs,
129 sdcnt->pollcnt, sdcnt->regfails,
130 sdcnt->tx_sderrs, sdcnt->fcqueued,
131 sdcnt->rxrtx, sdcnt->rx_toolong,
132 sdcnt->rxc_errors, sdcnt->rx_hdrfail,
133 sdcnt->rx_badhdr, sdcnt->rx_badseq,
134 sdcnt->fc_rcvd, sdcnt->fc_xoff,
135 sdcnt->fc_xon, sdcnt->rxglomfail,
136 sdcnt->rxglomframes, sdcnt->rxglompkts,
137 sdcnt->f2rxhdrs, sdcnt->f2rxdata,
138 sdcnt->f2txdata, sdcnt->f1regdata,
139 sdcnt->tickcnt, sdcnt->tx_ctlerrs,
140 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
141 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
142
143 return simple_read_from_buffer(data, count, ppos, buf, res);
144}
145
146static const struct file_operations brcmf_debugfs_sdio_counter_ops = {
147 .owner = THIS_MODULE,
148 .open = simple_open,
149 .read = brcmf_debugfs_sdio_counter_read
150}; 80};
151 81
152void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, 82static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
153 struct brcmf_sdio_count *sdcnt)
154{ 83{
155 struct dentry *dentry = drvr->dbgfs_dir; 84 struct brcmf_debugfs_entry *entry = inode->i_private;
156 85
157 if (!IS_ERR_OR_NULL(dentry)) 86 return single_open(f, entry->read, entry->drvr->bus_if->dev);
158 debugfs_create_file("counters", S_IRUGO, dentry,
159 sdcnt, &brcmf_debugfs_sdio_counter_ops);
160}
161
162static
163ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
164 size_t count, loff_t *ppos)
165{
166 struct brcmf_fws_stats *fwstats = f->private_data;
167 char buf[650];
168 int res;
169
170 /* only allow read from start */
171 if (*ppos > 0)
172 return 0;
173
174 res = scnprintf(buf, sizeof(buf),
175 "header_pulls: %u\n"
176 "header_only_pkt: %u\n"
177 "tlv_parse_failed: %u\n"
178 "tlv_invalid_type: %u\n"
179 "mac_update_fails: %u\n"
180 "ps_update_fails: %u\n"
181 "if_update_fails: %u\n"
182 "pkt2bus: %u\n"
183 "generic_error: %u\n"
184 "rollback_success: %u\n"
185 "rollback_failed: %u\n"
186 "delayq_full: %u\n"
187 "supprq_full: %u\n"
188 "txs_indicate: %u\n"
189 "txs_discard: %u\n"
190 "txs_suppr_core: %u\n"
191 "txs_suppr_ps: %u\n"
192 "txs_tossed: %u\n"
193 "txs_host_tossed: %u\n"
194 "bus_flow_block: %u\n"
195 "fws_flow_block: %u\n"
196 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
197 "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
198 fwstats->header_pulls,
199 fwstats->header_only_pkt,
200 fwstats->tlv_parse_failed,
201 fwstats->tlv_invalid_type,
202 fwstats->mac_update_failed,
203 fwstats->mac_ps_update_failed,
204 fwstats->if_update_failed,
205 fwstats->pkt2bus,
206 fwstats->generic_error,
207 fwstats->rollback_success,
208 fwstats->rollback_failed,
209 fwstats->delayq_full_error,
210 fwstats->supprq_full_error,
211 fwstats->txs_indicate,
212 fwstats->txs_discard,
213 fwstats->txs_supp_core,
214 fwstats->txs_supp_ps,
215 fwstats->txs_tossed,
216 fwstats->txs_host_tossed,
217 fwstats->bus_flow_block,
218 fwstats->fws_flow_block,
219 fwstats->send_pkts[0], fwstats->send_pkts[1],
220 fwstats->send_pkts[2], fwstats->send_pkts[3],
221 fwstats->send_pkts[4],
222 fwstats->requested_sent[0],
223 fwstats->requested_sent[1],
224 fwstats->requested_sent[2],
225 fwstats->requested_sent[3],
226 fwstats->requested_sent[4]);
227
228 return simple_read_from_buffer(data, count, ppos, buf, res);
229} 87}
230 88
231static const struct file_operations brcmf_debugfs_fws_stats_ops = { 89static const struct file_operations brcmf_debugfs_def_ops = {
232 .owner = THIS_MODULE, 90 .owner = THIS_MODULE,
233 .open = simple_open, 91 .open = brcmf_debugfs_entry_open,
234 .read = brcmf_debugfs_fws_stats_read 92 .release = single_release,
93 .read = seq_read,
94 .llseek = seq_lseek
235}; 95};
236 96
237void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, 97int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
238 struct brcmf_fws_stats *stats) 98 int (*read_fn)(struct seq_file *seq, void *data))
239{ 99{
240 struct dentry *dentry = drvr->dbgfs_dir; 100 struct dentry *dentry = drvr->dbgfs_dir;
101 struct brcmf_debugfs_entry *entry;
102
103 if (IS_ERR_OR_NULL(dentry))
104 return -ENOENT;
105
106 entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
107 if (!entry)
108 return -ENOMEM;
109
110 entry->read = read_fn;
111 entry->drvr = drvr;
112
113 dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
114 &brcmf_debugfs_def_ops);
241 115
242 if (!IS_ERR_OR_NULL(dentry)) 116 return PTR_ERR_OR_ZERO(dentry);
243 debugfs_create_file("fws_stats", S_IRUGO, dentry,
244 stats, &brcmf_debugfs_fws_stats_ops);
245} 117}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index ef52ed7abc69..6eade7c60c63 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -100,68 +100,6 @@ do { \
100 100
101extern int brcmf_msg_level; 101extern int brcmf_msg_level;
102 102
103/*
104 * hold counter variables used in brcmfmac sdio driver.
105 */
106struct brcmf_sdio_count {
107 uint intrcount; /* Count of device interrupt callbacks */
108 uint lastintrs; /* Count as of last watchdog timer */
109 uint pollcnt; /* Count of active polls */
110 uint regfails; /* Count of R_REG failures */
111 uint tx_sderrs; /* Count of tx attempts with sd errors */
112 uint fcqueued; /* Tx packets that got queued */
113 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
114 uint rx_toolong; /* Receive frames too long to receive */
115 uint rxc_errors; /* SDIO errors when reading control frames */
116 uint rx_hdrfail; /* SDIO errors on header reads */
117 uint rx_badhdr; /* Bad received headers (roosync?) */
118 uint rx_badseq; /* Mismatched rx sequence number */
119 uint fc_rcvd; /* Number of flow-control events received */
120 uint fc_xoff; /* Number which turned on flow-control */
121 uint fc_xon; /* Number which turned off flow-control */
122 uint rxglomfail; /* Failed deglom attempts */
123 uint rxglomframes; /* Number of glom frames (superframes) */
124 uint rxglompkts; /* Number of packets from glom frames */
125 uint f2rxhdrs; /* Number of header reads */
126 uint f2rxdata; /* Number of frame data reads */
127 uint f2txdata; /* Number of f2 frame writes */
128 uint f1regdata; /* Number of f1 register accesses */
129 uint tickcnt; /* Number of watchdog been schedule */
130 ulong tx_ctlerrs; /* Err of sending ctrl frames */
131 ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
132 ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
133 ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
134 ulong rx_readahead_cnt; /* packets where header read-ahead was used */
135};
136
137struct brcmf_fws_stats {
138 u32 tlv_parse_failed;
139 u32 tlv_invalid_type;
140 u32 header_only_pkt;
141 u32 header_pulls;
142 u32 pkt2bus;
143 u32 send_pkts[5];
144 u32 requested_sent[5];
145 u32 generic_error;
146 u32 mac_update_failed;
147 u32 mac_ps_update_failed;
148 u32 if_update_failed;
149 u32 packet_request_failed;
150 u32 credit_request_failed;
151 u32 rollback_success;
152 u32 rollback_failed;
153 u32 delayq_full_error;
154 u32 supprq_full_error;
155 u32 txs_indicate;
156 u32 txs_discard;
157 u32 txs_supp_core;
158 u32 txs_supp_ps;
159 u32 txs_tossed;
160 u32 txs_host_tossed;
161 u32 bus_flow_block;
162 u32 fws_flow_block;
163};
164
165struct brcmf_pub; 103struct brcmf_pub;
166#ifdef DEBUG 104#ifdef DEBUG
167void brcmf_debugfs_init(void); 105void brcmf_debugfs_init(void);
@@ -169,10 +107,8 @@ void brcmf_debugfs_exit(void);
169int brcmf_debugfs_attach(struct brcmf_pub *drvr); 107int brcmf_debugfs_attach(struct brcmf_pub *drvr);
170void brcmf_debugfs_detach(struct brcmf_pub *drvr); 108void brcmf_debugfs_detach(struct brcmf_pub *drvr);
171struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); 109struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
172void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, 110int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
173 struct brcmf_sdio_count *sdcnt); 111 int (*read_fn)(struct seq_file *seq, void *data));
174void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
175 struct brcmf_fws_stats *stats);
176#else 112#else
177static inline void brcmf_debugfs_init(void) 113static inline void brcmf_debugfs_init(void)
178{ 114{
@@ -187,9 +123,11 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
187static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) 123static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
188{ 124{
189} 125}
190static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, 126static inline
191 struct brcmf_fws_stats *stats) 127int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
128 int (*read_fn)(struct seq_file *seq, void *data))
192{ 129{
130 return 0;
193} 131}
194#endif 132#endif
195 133
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 2699441d4f41..347b4260f45b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -30,6 +30,7 @@
30#include "wl_cfg80211.h" 30#include "wl_cfg80211.h"
31#include "fwil.h" 31#include "fwil.h"
32#include "fwsignal.h" 32#include "fwsignal.h"
33#include "feature.h"
33#include "proto.h" 34#include "proto.h"
34 35
35MODULE_AUTHOR("Broadcom Corporation"); 36MODULE_AUTHOR("Broadcom Corporation");
@@ -937,6 +938,8 @@ int brcmf_bus_start(struct device *dev)
937 if (ret < 0) 938 if (ret < 0)
938 goto fail; 939 goto fail;
939 940
941 brcmf_feat_attach(drvr);
942
940 ret = brcmf_fws_init(drvr); 943 ret = brcmf_fws_init(drvr);
941 if (ret < 0) 944 if (ret < 0)
942 goto fail; 945 goto fail;
@@ -1074,16 +1077,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1074 return !err; 1077 return !err;
1075} 1078}
1076 1079
1077/*
1078 * return chip id and rev of the device encoded in u32.
1079 */
1080u32 brcmf_get_chip_info(struct brcmf_if *ifp)
1081{
1082 struct brcmf_bus *bus = ifp->drvr->bus_if;
1083
1084 return bus->chip << 4 | bus->chiprev;
1085}
1086
1087static void brcmf_driver_register(struct work_struct *work) 1080static void brcmf_driver_register(struct work_struct *work)
1088{ 1081{
1089#ifdef CONFIG_BRCMFMAC_SDIO 1082#ifdef CONFIG_BRCMFMAC_SDIO
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 8fa0dbbbda72..67d91d5cc13d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -391,6 +391,40 @@ struct brcmf_sdio_hdrinfo {
391 u16 tail_pad; 391 u16 tail_pad;
392}; 392};
393 393
394/*
395 * hold counter variables
396 */
397struct brcmf_sdio_count {
398 uint intrcount; /* Count of device interrupt callbacks */
399 uint lastintrs; /* Count as of last watchdog timer */
400 uint pollcnt; /* Count of active polls */
401 uint regfails; /* Count of R_REG failures */
402 uint tx_sderrs; /* Count of tx attempts with sd errors */
403 uint fcqueued; /* Tx packets that got queued */
404 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
405 uint rx_toolong; /* Receive frames too long to receive */
406 uint rxc_errors; /* SDIO errors when reading control frames */
407 uint rx_hdrfail; /* SDIO errors on header reads */
408 uint rx_badhdr; /* Bad received headers (roosync?) */
409 uint rx_badseq; /* Mismatched rx sequence number */
410 uint fc_rcvd; /* Number of flow-control events received */
411 uint fc_xoff; /* Number which turned on flow-control */
412 uint fc_xon; /* Number which turned off flow-control */
413 uint rxglomfail; /* Failed deglom attempts */
414 uint rxglomframes; /* Number of glom frames (superframes) */
415 uint rxglompkts; /* Number of packets from glom frames */
416 uint f2rxhdrs; /* Number of header reads */
417 uint f2rxdata; /* Number of frame data reads */
418 uint f2txdata; /* Number of f2 frame writes */
419 uint f1regdata; /* Number of f1 register accesses */
420 uint tickcnt; /* Number of watchdog been schedule */
421 ulong tx_ctlerrs; /* Err of sending ctrl frames */
422 ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
423 ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
424 ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
425 ulong rx_readahead_cnt; /* packets where header read-ahead was used */
426};
427
394/* misc chip info needed by some of the routines */ 428/* misc chip info needed by some of the routines */
395/* Private data for SDIO bus interaction */ 429/* Private data for SDIO bus interaction */
396struct brcmf_sdio { 430struct brcmf_sdio {
@@ -620,40 +654,46 @@ enum brcmf_firmware_type {
620 name ## _FIRMWARE_NAME, name ## _NVRAM_NAME 654 name ## _FIRMWARE_NAME, name ## _NVRAM_NAME
621 655
622static const struct brcmf_firmware_names brcmf_fwname_data[] = { 656static const struct brcmf_firmware_names brcmf_fwname_data[] = {
623 { BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) }, 657 { BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
624 { BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) }, 658 { BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
625 { BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) }, 659 { BRCM_CC_43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
626 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, 660 { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
627 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, 661 { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
628 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, 662 { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
629 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, 663 { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
630 { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, 664 { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
631 { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, 665 { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
632 { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } 666 { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
633}; 667};
634 668
635static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci, 669static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
636 enum brcmf_firmware_type type) 670 struct brcmf_sdio_dev *sdiodev)
637{ 671{
638 int i; 672 int i;
639 673
640 for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) { 674 for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
641 if (brcmf_fwname_data[i].chipid == ci->chip && 675 if (brcmf_fwname_data[i].chipid == ci->chip &&
642 brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) { 676 brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
643 switch (type) { 677 break;
644 case BRCMF_FIRMWARE_BIN:
645 return brcmf_fwname_data[i].bin;
646 case BRCMF_FIRMWARE_NVRAM:
647 return brcmf_fwname_data[i].nv;
648 default:
649 brcmf_err("invalid firmware type (%d)\n", type);
650 return NULL;
651 }
652 }
653 } 678 }
654 brcmf_err("Unknown chipid %d [%d]\n", 679
655 ci->chip, ci->chiprev); 680 if (i == ARRAY_SIZE(brcmf_fwname_data)) {
656 return NULL; 681 brcmf_err("Unknown chipid %d [%d]\n", ci->chip, ci->chiprev);
682 return -ENODEV;
683 }
684
685 /* check if firmware path is provided by module parameter */
686 if (brcmf_firmware_path[0] != '\0') {
687 if (brcmf_firmware_path[strlen(brcmf_firmware_path) - 1] != '/')
688 strcat(brcmf_firmware_path, "/");
689
690 strcpy(sdiodev->fw_name, brcmf_firmware_path);
691 strcpy(sdiodev->nvram_name, brcmf_firmware_path);
692 }
693 strcat(sdiodev->fw_name, brcmf_fwname_data[i].bin);
694 strcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv);
695
696 return 0;
657} 697}
658 698
659static void pkt_align(struct sk_buff *p, int len, int align) 699static void pkt_align(struct sk_buff *p, int len, int align)
@@ -2898,16 +2938,13 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2898} 2938}
2899 2939
2900#ifdef DEBUG 2940#ifdef DEBUG
2901static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, 2941static int brcmf_sdio_dump_console(struct seq_file *seq, struct brcmf_sdio *bus,
2902 struct sdpcm_shared *sh, char __user *data, 2942 struct sdpcm_shared *sh)
2903 size_t count)
2904{ 2943{
2905 u32 addr, console_ptr, console_size, console_index; 2944 u32 addr, console_ptr, console_size, console_index;
2906 char *conbuf = NULL; 2945 char *conbuf = NULL;
2907 __le32 sh_val; 2946 __le32 sh_val;
2908 int rv; 2947 int rv;
2909 loff_t pos = 0;
2910 int nbytes = 0;
2911 2948
2912 /* obtain console information from device memory */ 2949 /* obtain console information from device memory */
2913 addr = sh->console_addr + offsetof(struct rte_console, log_le); 2950 addr = sh->console_addr + offsetof(struct rte_console, log_le);
@@ -2945,33 +2982,24 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
2945 if (rv < 0) 2982 if (rv < 0)
2946 goto done; 2983 goto done;
2947 2984
2948 rv = simple_read_from_buffer(data, count, &pos, 2985 rv = seq_write(seq, conbuf + console_index,
2949 conbuf + console_index, 2986 console_size - console_index);
2950 console_size - console_index);
2951 if (rv < 0) 2987 if (rv < 0)
2952 goto done; 2988 goto done;
2953 2989
2954 nbytes = rv; 2990 if (console_index > 0)
2955 if (console_index > 0) { 2991 rv = seq_write(seq, conbuf, console_index - 1);
2956 pos = 0; 2992
2957 rv = simple_read_from_buffer(data+nbytes, count, &pos,
2958 conbuf, console_index - 1);
2959 if (rv < 0)
2960 goto done;
2961 rv += nbytes;
2962 }
2963done: 2993done:
2964 vfree(conbuf); 2994 vfree(conbuf);
2965 return rv; 2995 return rv;
2966} 2996}
2967 2997
2968static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, 2998static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
2969 char __user *data, size_t count) 2999 struct sdpcm_shared *sh)
2970{ 3000{
2971 int error, res; 3001 int error;
2972 char buf[350];
2973 struct brcmf_trap_info tr; 3002 struct brcmf_trap_info tr;
2974 loff_t pos = 0;
2975 3003
2976 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) { 3004 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) {
2977 brcmf_dbg(INFO, "no trap in firmware\n"); 3005 brcmf_dbg(INFO, "no trap in firmware\n");
@@ -2983,34 +3011,30 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2983 if (error < 0) 3011 if (error < 0)
2984 return error; 3012 return error;
2985 3013
2986 res = scnprintf(buf, sizeof(buf), 3014 seq_printf(seq,
2987 "dongle trap info: type 0x%x @ epc 0x%08x\n" 3015 "dongle trap info: type 0x%x @ epc 0x%08x\n"
2988 " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" 3016 " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
2989 " lr 0x%08x pc 0x%08x offset 0x%x\n" 3017 " lr 0x%08x pc 0x%08x offset 0x%x\n"
2990 " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" 3018 " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
2991 " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", 3019 " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
2992 le32_to_cpu(tr.type), le32_to_cpu(tr.epc), 3020 le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
2993 le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), 3021 le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
2994 le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), 3022 le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
2995 le32_to_cpu(tr.pc), sh->trap_addr, 3023 le32_to_cpu(tr.pc), sh->trap_addr,
2996 le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), 3024 le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
2997 le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), 3025 le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
2998 le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), 3026 le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
2999 le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); 3027 le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
3000 3028
3001 return simple_read_from_buffer(data, count, &pos, buf, res); 3029 return 0;
3002} 3030}
3003 3031
3004static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, 3032static int brcmf_sdio_assert_info(struct seq_file *seq, struct brcmf_sdio *bus,
3005 struct sdpcm_shared *sh, char __user *data, 3033 struct sdpcm_shared *sh)
3006 size_t count)
3007{ 3034{
3008 int error = 0; 3035 int error = 0;
3009 char buf[200];
3010 char file[80] = "?"; 3036 char file[80] = "?";
3011 char expr[80] = "<???>"; 3037 char expr[80] = "<???>";
3012 int res;
3013 loff_t pos = 0;
3014 3038
3015 if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { 3039 if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
3016 brcmf_dbg(INFO, "firmware not built with -assert\n"); 3040 brcmf_dbg(INFO, "firmware not built with -assert\n");
@@ -3035,10 +3059,9 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
3035 } 3059 }
3036 sdio_release_host(bus->sdiodev->func[1]); 3060 sdio_release_host(bus->sdiodev->func[1]);
3037 3061
3038 res = scnprintf(buf, sizeof(buf), 3062 seq_printf(seq, "dongle assert: %s:%d: assert(%s)\n",
3039 "dongle assert: %s:%d: assert(%s)\n", 3063 file, sh->assert_line, expr);
3040 file, sh->assert_line, expr); 3064 return 0;
3041 return simple_read_from_buffer(data, count, &pos, buf, res);
3042} 3065}
3043 3066
3044static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) 3067static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
@@ -3062,59 +3085,75 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
3062 return 0; 3085 return 0;
3063} 3086}
3064 3087
3065static int brcmf_sdio_died_dump(struct brcmf_sdio *bus, char __user *data, 3088static int brcmf_sdio_died_dump(struct seq_file *seq, struct brcmf_sdio *bus)
3066 size_t count, loff_t *ppos)
3067{ 3089{
3068 int error = 0; 3090 int error = 0;
3069 struct sdpcm_shared sh; 3091 struct sdpcm_shared sh;
3070 int nbytes = 0;
3071 loff_t pos = *ppos;
3072
3073 if (pos != 0)
3074 return 0;
3075 3092
3076 error = brcmf_sdio_readshared(bus, &sh); 3093 error = brcmf_sdio_readshared(bus, &sh);
3077 if (error < 0) 3094 if (error < 0)
3078 goto done; 3095 goto done;
3079 3096
3080 error = brcmf_sdio_assert_info(bus, &sh, data, count); 3097 error = brcmf_sdio_assert_info(seq, bus, &sh);
3081 if (error < 0) 3098 if (error < 0)
3082 goto done; 3099 goto done;
3083 nbytes = error;
3084 3100
3085 error = brcmf_sdio_trap_info(bus, &sh, data+nbytes, count); 3101 error = brcmf_sdio_trap_info(seq, bus, &sh);
3086 if (error < 0) 3102 if (error < 0)
3087 goto done; 3103 goto done;
3088 nbytes += error;
3089 3104
3090 error = brcmf_sdio_dump_console(bus, &sh, data+nbytes, count); 3105 error = brcmf_sdio_dump_console(seq, bus, &sh);
3091 if (error < 0)
3092 goto done;
3093 nbytes += error;
3094 3106
3095 error = nbytes;
3096 *ppos += nbytes;
3097done: 3107done:
3098 return error; 3108 return error;
3099} 3109}
3100 3110
3101static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data, 3111static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data)
3102 size_t count, loff_t *ppos)
3103{ 3112{
3104 struct brcmf_sdio *bus = f->private_data; 3113 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
3105 int res; 3114 struct brcmf_sdio *bus = bus_if->bus_priv.sdio->bus;
3106 3115
3107 res = brcmf_sdio_died_dump(bus, data, count, ppos); 3116 return brcmf_sdio_died_dump(seq, bus);
3108 if (res > 0)
3109 *ppos += res;
3110 return (ssize_t)res;
3111} 3117}
3112 3118
3113static const struct file_operations brcmf_sdio_forensic_ops = { 3119static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data)
3114 .owner = THIS_MODULE, 3120{
3115 .open = simple_open, 3121 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
3116 .read = brcmf_sdio_forensic_read 3122 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3117}; 3123 struct brcmf_sdio_count *sdcnt = &sdiodev->bus->sdcnt;
3124
3125 seq_printf(seq,
3126 "intrcount: %u\nlastintrs: %u\n"
3127 "pollcnt: %u\nregfails: %u\n"
3128 "tx_sderrs: %u\nfcqueued: %u\n"
3129 "rxrtx: %u\nrx_toolong: %u\n"
3130 "rxc_errors: %u\nrx_hdrfail: %u\n"
3131 "rx_badhdr: %u\nrx_badseq: %u\n"
3132 "fc_rcvd: %u\nfc_xoff: %u\n"
3133 "fc_xon: %u\nrxglomfail: %u\n"
3134 "rxglomframes: %u\nrxglompkts: %u\n"
3135 "f2rxhdrs: %u\nf2rxdata: %u\n"
3136 "f2txdata: %u\nf1regdata: %u\n"
3137 "tickcnt: %u\ntx_ctlerrs: %lu\n"
3138 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
3139 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
3140 sdcnt->intrcount, sdcnt->lastintrs,
3141 sdcnt->pollcnt, sdcnt->regfails,
3142 sdcnt->tx_sderrs, sdcnt->fcqueued,
3143 sdcnt->rxrtx, sdcnt->rx_toolong,
3144 sdcnt->rxc_errors, sdcnt->rx_hdrfail,
3145 sdcnt->rx_badhdr, sdcnt->rx_badseq,
3146 sdcnt->fc_rcvd, sdcnt->fc_xoff,
3147 sdcnt->fc_xon, sdcnt->rxglomfail,
3148 sdcnt->rxglomframes, sdcnt->rxglompkts,
3149 sdcnt->f2rxhdrs, sdcnt->f2rxdata,
3150 sdcnt->f2txdata, sdcnt->f1regdata,
3151 sdcnt->tickcnt, sdcnt->tx_ctlerrs,
3152 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
3153 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
3154
3155 return 0;
3156}
3118 3157
3119static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) 3158static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3120{ 3159{
@@ -3124,9 +3163,9 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3124 if (IS_ERR_OR_NULL(dentry)) 3163 if (IS_ERR_OR_NULL(dentry))
3125 return; 3164 return;
3126 3165
3127 debugfs_create_file("forensics", S_IRUGO, dentry, bus, 3166 brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
3128 &brcmf_sdio_forensic_ops); 3167 brcmf_debugfs_add_entry(drvr, "counters",
3129 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); 3168 brcmf_debugfs_sdio_count_read);
3130 debugfs_create_u32("console_interval", 0644, dentry, 3169 debugfs_create_u32("console_interval", 0644, dentry,
3131 &bus->console_interval); 3170 &bus->console_interval);
3132} 3171}
@@ -3598,17 +3637,17 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
3598 return; 3637 return;
3599 3638
3600 switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { 3639 switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
3601 case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): 3640 case SDIOD_DRVSTR_KEY(BRCM_CC_4330_CHIP_ID, 12):
3602 str_tab = sdiod_drvstr_tab1_1v8; 3641 str_tab = sdiod_drvstr_tab1_1v8;
3603 str_mask = 0x00003800; 3642 str_mask = 0x00003800;
3604 str_shift = 11; 3643 str_shift = 11;
3605 break; 3644 break;
3606 case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17): 3645 case SDIOD_DRVSTR_KEY(BRCM_CC_4334_CHIP_ID, 17):
3607 str_tab = sdiod_drvstr_tab6_1v8; 3646 str_tab = sdiod_drvstr_tab6_1v8;
3608 str_mask = 0x00001800; 3647 str_mask = 0x00001800;
3609 str_shift = 11; 3648 str_shift = 11;
3610 break; 3649 break;
3611 case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): 3650 case SDIOD_DRVSTR_KEY(BRCM_CC_43143_CHIP_ID, 17):
3612 /* note: 43143 does not support tristate */ 3651 /* note: 43143 does not support tristate */
3613 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; 3652 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
3614 if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) { 3653 if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
@@ -3619,7 +3658,7 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
3619 brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n", 3658 brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
3620 ci->name, drivestrength); 3659 ci->name, drivestrength);
3621 break; 3660 break;
3622 case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): 3661 case SDIOD_DRVSTR_KEY(BRCM_CC_43362_CHIP_ID, 13):
3623 str_tab = sdiod_drive_strength_tab5_1v8; 3662 str_tab = sdiod_drive_strength_tab5_1v8;
3624 str_mask = 0x00003800; 3663 str_mask = 0x00003800;
3625 str_shift = 11; 3664 str_shift = 11;
@@ -3720,12 +3759,12 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
3720 u32 val, rev; 3759 u32 val, rev;
3721 3760
3722 val = brcmf_sdiod_regrl(sdiodev, addr, NULL); 3761 val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
3723 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && 3762 if (sdiodev->func[0]->device == BRCM_SDIO_4335_4339_DEVICE_ID &&
3724 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { 3763 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
3725 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; 3764 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
3726 if (rev >= 2) { 3765 if (rev >= 2) {
3727 val &= ~CID_ID_MASK; 3766 val &= ~CID_ID_MASK;
3728 val |= BCM4339_CHIP_ID; 3767 val |= BRCM_CC_4339_CHIP_ID;
3729 } 3768 }
3730 } 3769 }
3731 return val; 3770 return val;
@@ -4127,11 +4166,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4127 brcmf_sdio_debugfs_create(bus); 4166 brcmf_sdio_debugfs_create(bus);
4128 brcmf_dbg(INFO, "completed!!\n"); 4167 brcmf_dbg(INFO, "completed!!\n");
4129 4168
4169 ret = brcmf_sdio_get_fwnames(bus->ci, sdiodev);
4170 if (ret)
4171 goto fail;
4172
4130 ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, 4173 ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
4131 brcmf_sdio_get_fwname(bus->ci, 4174 sdiodev->fw_name, sdiodev->nvram_name,
4132 BRCMF_FIRMWARE_BIN),
4133 brcmf_sdio_get_fwname(bus->ci,
4134 BRCMF_FIRMWARE_NVRAM),
4135 brcmf_sdio_firmware_callback); 4175 brcmf_sdio_firmware_callback);
4136 if (ret != 0) { 4176 if (ret != 0) {
4137 brcmf_err("async firmware request failed: %d\n", ret); 4177 brcmf_err("async firmware request failed: %d\n", ret);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
new file mode 100644
index 000000000000..50877e3c5d2f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
@@ -0,0 +1,136 @@
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
17#include <linux/netdevice.h>
18
19#include <brcm_hw_ids.h>
20#include "dhd.h"
21#include "dhd_bus.h"
22#include "dhd_dbg.h"
23#include "fwil.h"
24#include "feature.h"
25
26/*
27 * firmware error code received if iovar is unsupported.
28 */
29#define EBRCMF_FEAT_UNSUPPORTED 23
30
31/*
32 * expand feature list to array of feature strings.
33 */
34#define BRCMF_FEAT_DEF(_f) \
35 #_f,
36static const char *brcmf_feat_names[] = {
37 BRCMF_FEAT_LIST
38};
39#undef BRCMF_FEAT_DEF
40
41#ifdef DEBUG
42/*
43 * expand quirk list to array of quirk strings.
44 */
45#define BRCMF_QUIRK_DEF(_q) \
46 #_q,
47static const char * const brcmf_quirk_names[] = {
48 BRCMF_QUIRK_LIST
49};
50#undef BRCMF_QUIRK_DEF
51
52/**
53 * brcmf_feat_debugfs_read() - expose feature info to debugfs.
54 *
55 * @seq: sequence for debugfs entry.
56 * @data: raw data pointer.
57 */
58static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data)
59{
60 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
61 u32 feats = bus_if->drvr->feat_flags;
62 u32 quirks = bus_if->drvr->chip_quirks;
63 int id;
64
65 seq_printf(seq, "Features: %08x\n", feats);
66 for (id = 0; id < BRCMF_FEAT_LAST; id++)
67 if (feats & BIT(id))
68 seq_printf(seq, "\t%s\n", brcmf_feat_names[id]);
69 seq_printf(seq, "\nQuirks: %08x\n", quirks);
70 for (id = 0; id < BRCMF_FEAT_QUIRK_LAST; id++)
71 if (quirks & BIT(id))
72 seq_printf(seq, "\t%s\n", brcmf_quirk_names[id]);
73 return 0;
74}
75#else
76static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data)
77{
78 return 0;
79}
80#endif /* DEBUG */
81
82/**
83 * brcmf_feat_iovar_int_get() - determine feature through iovar query.
84 *
85 * @ifp: interface to query.
86 * @id: feature id.
87 * @name: iovar name.
88 */
89static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
90 enum brcmf_feat_id id, char *name)
91{
92 u32 data;
93 int err;
94
95 err = brcmf_fil_iovar_int_get(ifp, name, &data);
96 if (err == 0) {
97 brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
98 ifp->drvr->feat_flags |= BIT(id);
99 } else {
100 brcmf_dbg(TRACE, "%s feature check failed: %d\n",
101 brcmf_feat_names[id], err);
102 }
103}
104
105void brcmf_feat_attach(struct brcmf_pub *drvr)
106{
107 struct brcmf_if *ifp = drvr->iflist[0];
108
109 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
110
111 /* set chip related quirks */
112 switch (drvr->bus_if->chip) {
113 case BRCM_CC_43236_CHIP_ID:
114 drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_AUTO_AUTH);
115 break;
116 case BRCM_CC_4329_CHIP_ID:
117 drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_NEED_MPC);
118 break;
119 default:
120 /* no quirks */
121 break;
122 }
123
124 brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read);
125}
126
127bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id)
128{
129 return (ifp->drvr->feat_flags & BIT(id));
130}
131
132bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp,
133 enum brcmf_feat_quirk quirk)
134{
135 return (ifp->drvr->chip_quirks & BIT(quirk));
136}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
new file mode 100644
index 000000000000..961d175f8afb
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
@@ -0,0 +1,86 @@
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_FEATURE_H
17#define _BRCMF_FEATURE_H
18
19/*
20 * Features:
21 *
22 * MCHAN: multi-channel for concurrent P2P.
23 */
24#define BRCMF_FEAT_LIST \
25 BRCMF_FEAT_DEF(MCHAN)
26/*
27 * Quirks:
28 *
29 * AUTO_AUTH: workaround needed for automatic authentication type.
30 * NEED_MPC: driver needs to disable MPC during scanning operation.
31 */
32#define BRCMF_QUIRK_LIST \
33 BRCMF_QUIRK_DEF(AUTO_AUTH) \
34 BRCMF_QUIRK_DEF(NEED_MPC)
35
36#define BRCMF_FEAT_DEF(_f) \
37 BRCMF_FEAT_ ## _f,
38/*
39 * expand feature list to enumeration.
40 */
41enum brcmf_feat_id {
42 BRCMF_FEAT_LIST
43 BRCMF_FEAT_LAST
44};
45#undef BRCMF_FEAT_DEF
46
47#define BRCMF_QUIRK_DEF(_q) \
48 BRCMF_FEAT_QUIRK_ ## _q,
49/*
50 * expand quirk list to enumeration.
51 */
52enum brcmf_feat_quirk {
53 BRCMF_QUIRK_LIST
54 BRCMF_FEAT_QUIRK_LAST
55};
56#undef BRCMF_QUIRK_DEF
57
58/**
59 * brcmf_feat_attach() - determine features and quirks.
60 *
61 * @drvr: driver instance.
62 */
63void brcmf_feat_attach(struct brcmf_pub *drvr);
64
65/**
66 * brcmf_feat_is_enabled() - query feature.
67 *
68 * @ifp: interface instance.
69 * @id: feature id to check.
70 *
71 * Return: true is feature is enabled; otherwise false.
72 */
73bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id);
74
75/**
76 * brcmf_feat_is_quirk_enabled() - query chip quirk.
77 *
78 * @ifp: interface instance.
79 * @quirk: quirk id to check.
80 *
81 * Return: true is quirk is enabled; otherwise false.
82 */
83bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp,
84 enum brcmf_feat_quirk quirk);
85
86#endif /* _BRCMF_FEATURE_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 7b7d237c1ddb..8ea9f283d2b8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -18,10 +18,15 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include <linux/module.h>
21 22
22#include "dhd_dbg.h" 23#include "dhd_dbg.h"
23#include "firmware.h" 24#include "firmware.h"
24 25
26char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
27module_param_string(firmware_path, brcmf_firmware_path,
28 BRCMF_FW_PATH_LEN, 0440);
29
25enum nvram_parser_state { 30enum nvram_parser_state {
26 IDLE, 31 IDLE,
27 KEY, 32 KEY,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
index 6431bfd7afff..4d3482356b77 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
@@ -21,6 +21,11 @@
21#define BRCMF_FW_REQ_FLAGS 0x00F0 21#define BRCMF_FW_REQ_FLAGS 0x00F0
22#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010 22#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
23 23
24#define BRCMF_FW_PATH_LEN 256
25#define BRCMF_FW_NAME_LEN 32
26
27extern char brcmf_firmware_path[];
28
24void brcmf_fw_nvram_free(void *nvram); 29void brcmf_fw_nvram_free(void *nvram);
25/* 30/*
26 * Request firmware(s) asynchronously. When the asynchronous request 31 * Request firmware(s) asynchronously. When the asynchronous request
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 699908de314a..d42f7d04b65f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -454,6 +454,34 @@ struct brcmf_fws_macdesc_table {
454 struct brcmf_fws_mac_descriptor other; 454 struct brcmf_fws_mac_descriptor other;
455}; 455};
456 456
457struct brcmf_fws_stats {
458 u32 tlv_parse_failed;
459 u32 tlv_invalid_type;
460 u32 header_only_pkt;
461 u32 header_pulls;
462 u32 pkt2bus;
463 u32 send_pkts[5];
464 u32 requested_sent[5];
465 u32 generic_error;
466 u32 mac_update_failed;
467 u32 mac_ps_update_failed;
468 u32 if_update_failed;
469 u32 packet_request_failed;
470 u32 credit_request_failed;
471 u32 rollback_success;
472 u32 rollback_failed;
473 u32 delayq_full_error;
474 u32 supprq_full_error;
475 u32 txs_indicate;
476 u32 txs_discard;
477 u32 txs_supp_core;
478 u32 txs_supp_ps;
479 u32 txs_tossed;
480 u32 txs_host_tossed;
481 u32 bus_flow_block;
482 u32 fws_flow_block;
483};
484
457struct brcmf_fws_info { 485struct brcmf_fws_info {
458 struct brcmf_pub *drvr; 486 struct brcmf_pub *drvr;
459 spinlock_t spinlock; 487 spinlock_t spinlock;
@@ -2017,6 +2045,75 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
2017 brcmf_fws_unlock(fws); 2045 brcmf_fws_unlock(fws);
2018} 2046}
2019 2047
2048#ifdef DEBUG
2049static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
2050{
2051 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
2052 struct brcmf_fws_stats *fwstats = &bus_if->drvr->fws->stats;
2053
2054 seq_printf(seq,
2055 "header_pulls: %u\n"
2056 "header_only_pkt: %u\n"
2057 "tlv_parse_failed: %u\n"
2058 "tlv_invalid_type: %u\n"
2059 "mac_update_fails: %u\n"
2060 "ps_update_fails: %u\n"
2061 "if_update_fails: %u\n"
2062 "pkt2bus: %u\n"
2063 "generic_error: %u\n"
2064 "rollback_success: %u\n"
2065 "rollback_failed: %u\n"
2066 "delayq_full: %u\n"
2067 "supprq_full: %u\n"
2068 "txs_indicate: %u\n"
2069 "txs_discard: %u\n"
2070 "txs_suppr_core: %u\n"
2071 "txs_suppr_ps: %u\n"
2072 "txs_tossed: %u\n"
2073 "txs_host_tossed: %u\n"
2074 "bus_flow_block: %u\n"
2075 "fws_flow_block: %u\n"
2076 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
2077 "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
2078 fwstats->header_pulls,
2079 fwstats->header_only_pkt,
2080 fwstats->tlv_parse_failed,
2081 fwstats->tlv_invalid_type,
2082 fwstats->mac_update_failed,
2083 fwstats->mac_ps_update_failed,
2084 fwstats->if_update_failed,
2085 fwstats->pkt2bus,
2086 fwstats->generic_error,
2087 fwstats->rollback_success,
2088 fwstats->rollback_failed,
2089 fwstats->delayq_full_error,
2090 fwstats->supprq_full_error,
2091 fwstats->txs_indicate,
2092 fwstats->txs_discard,
2093 fwstats->txs_supp_core,
2094 fwstats->txs_supp_ps,
2095 fwstats->txs_tossed,
2096 fwstats->txs_host_tossed,
2097 fwstats->bus_flow_block,
2098 fwstats->fws_flow_block,
2099 fwstats->send_pkts[0], fwstats->send_pkts[1],
2100 fwstats->send_pkts[2], fwstats->send_pkts[3],
2101 fwstats->send_pkts[4],
2102 fwstats->requested_sent[0],
2103 fwstats->requested_sent[1],
2104 fwstats->requested_sent[2],
2105 fwstats->requested_sent[3],
2106 fwstats->requested_sent[4]);
2107
2108 return 0;
2109}
2110#else
2111static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
2112{
2113 return 0;
2114}
2115#endif
2116
2020int brcmf_fws_init(struct brcmf_pub *drvr) 2117int brcmf_fws_init(struct brcmf_pub *drvr)
2021{ 2118{
2022 struct brcmf_fws_info *fws; 2119 struct brcmf_fws_info *fws;
@@ -2107,7 +2204,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
2107 BRCMF_FWS_PSQ_LEN); 2204 BRCMF_FWS_PSQ_LEN);
2108 2205
2109 /* create debugfs file for statistics */ 2206 /* create debugfs file for statistics */
2110 brcmf_debugfs_create_fws_stats(drvr, &fws->stats); 2207 brcmf_debugfs_add_entry(drvr, "fws_stats",
2208 brcmf_debugfs_fws_stats_read);
2111 2209
2112 brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", 2210 brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n",
2113 fws->fw_signals ? "enabled" : "disabled", tlv); 2211 fws->fw_signals ? "enabled" : "disabled", tlv);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 3deab7959a0d..6c5e585ccda9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -18,6 +18,8 @@
18#define _BRCM_SDH_H_ 18#define _BRCM_SDH_H_
19 19
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21#include <linux/firmware.h>
22#include "firmware.h"
21 23
22#define SDIO_FUNC_0 0 24#define SDIO_FUNC_0 0
23#define SDIO_FUNC_1 1 25#define SDIO_FUNC_1 1
@@ -182,6 +184,8 @@ struct brcmf_sdio_dev {
182 uint max_segment_size; 184 uint max_segment_size;
183 uint txglomsz; 185 uint txglomsz;
184 struct sg_table sgtable; 186 struct sg_table sgtable;
187 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
188 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
185}; 189};
186 190
187/* sdio core registers */ 191/* sdio core registers */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index b732a99e402c..dc135915470d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -21,6 +21,7 @@
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22 22
23#include <brcmu_utils.h> 23#include <brcmu_utils.h>
24#include <brcm_hw_ids.h>
24#include <brcmu_wifi.h> 25#include <brcmu_wifi.h>
25#include <dhd_bus.h> 26#include <dhd_bus.h>
26#include <dhd_dbg.h> 27#include <dhd_dbg.h>
@@ -913,16 +914,16 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
913static bool brcmf_usb_chip_support(int chipid, int chiprev) 914static bool brcmf_usb_chip_support(int chipid, int chiprev)
914{ 915{
915 switch(chipid) { 916 switch(chipid) {
916 case 43143: 917 case BRCM_CC_43143_CHIP_ID:
917 return true; 918 return true;
918 case 43235: 919 case BRCM_CC_43235_CHIP_ID:
919 case 43236: 920 case BRCM_CC_43236_CHIP_ID:
920 case 43238: 921 case BRCM_CC_43238_CHIP_ID:
921 return (chiprev == 3); 922 return (chiprev == 3);
922 case 43242: 923 case BRCM_CC_43242_CHIP_ID:
923 return true; 924 return true;
924 case 43566: 925 case BRCM_CC_43566_CHIP_ID:
925 case 43569: 926 case BRCM_CC_43569_CHIP_ID:
926 return true; 927 return true;
927 default: 928 default:
928 break; 929 break;
@@ -1016,16 +1017,16 @@ static int check_file(const u8 *headers)
1016static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo) 1017static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
1017{ 1018{
1018 switch (devinfo->bus_pub.devid) { 1019 switch (devinfo->bus_pub.devid) {
1019 case 43143: 1020 case BRCM_CC_43143_CHIP_ID:
1020 return BRCMF_USB_43143_FW_NAME; 1021 return BRCMF_USB_43143_FW_NAME;
1021 case 43235: 1022 case BRCM_CC_43235_CHIP_ID:
1022 case 43236: 1023 case BRCM_CC_43236_CHIP_ID:
1023 case 43238: 1024 case BRCM_CC_43238_CHIP_ID:
1024 return BRCMF_USB_43236_FW_NAME; 1025 return BRCMF_USB_43236_FW_NAME;
1025 case 43242: 1026 case BRCM_CC_43242_CHIP_ID:
1026 return BRCMF_USB_43242_FW_NAME; 1027 return BRCMF_USB_43242_FW_NAME;
1027 case 43566: 1028 case BRCM_CC_43566_CHIP_ID:
1028 case 43569: 1029 case BRCM_CC_43569_CHIP_ID:
1029 return BRCMF_USB_43569_FW_NAME; 1030 return BRCMF_USB_43569_FW_NAME;
1030 default: 1031 default:
1031 return NULL; 1032 return NULL;
@@ -1366,21 +1367,17 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
1366 brcmf_usb_probe_phase2); 1367 brcmf_usb_probe_phase2);
1367} 1368}
1368 1369
1369#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c 1370#define BRCMF_USB_DEVICE(dev_id) \
1370#define BRCMF_USB_DEVICE_ID_43143 0xbd1e 1371 { USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) }
1371#define BRCMF_USB_DEVICE_ID_43236 0xbd17
1372#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
1373#define BRCMF_USB_DEVICE_ID_43569 0xbd27
1374#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
1375 1372
1376static struct usb_device_id brcmf_usb_devid_table[] = { 1373static struct usb_device_id brcmf_usb_devid_table[] = {
1377 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) }, 1374 BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID),
1378 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) }, 1375 BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
1379 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) }, 1376 BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
1380 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43569) }, 1377 BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
1381 /* special entry for device with firmware loaded and running */ 1378 /* special entry for device with firmware loaded and running */
1382 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, 1379 BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
1383 { } 1380 { /* end: all zeroes */ }
1384}; 1381};
1385 1382
1386MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table); 1383MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 9682cf213ec4..48078a321716 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -33,6 +33,7 @@
33#include "p2p.h" 33#include "p2p.h"
34#include "btcoex.h" 34#include "btcoex.h"
35#include "wl_cfg80211.h" 35#include "wl_cfg80211.h"
36#include "feature.h"
36#include "fwil.h" 37#include "fwil.h"
37#include "vendor.h" 38#include "vendor.h"
38 39
@@ -102,24 +103,6 @@ static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
102 return true; 103 return true;
103} 104}
104 105
105#define CHAN2G(_channel, _freq, _flags) { \
106 .band = IEEE80211_BAND_2GHZ, \
107 .center_freq = (_freq), \
108 .hw_value = (_channel), \
109 .flags = (_flags), \
110 .max_antenna_gain = 0, \
111 .max_power = 30, \
112}
113
114#define CHAN5G(_channel, _flags) { \
115 .band = IEEE80211_BAND_5GHZ, \
116 .center_freq = 5000 + (5 * (_channel)), \
117 .hw_value = (_channel), \
118 .flags = (_flags), \
119 .max_antenna_gain = 0, \
120 .max_power = 30, \
121}
122
123#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2) 106#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
124#define RATETAB_ENT(_rateid, _flags) \ 107#define RATETAB_ENT(_rateid, _flags) \
125 { \ 108 { \
@@ -148,58 +131,17 @@ static struct ieee80211_rate __wl_rates[] = {
148#define wl_g_rates (__wl_rates + 0) 131#define wl_g_rates (__wl_rates + 0)
149#define wl_g_rates_size 12 132#define wl_g_rates_size 12
150 133
151static struct ieee80211_channel __wl_2ghz_channels[] = { 134/* Band templates duplicated per wiphy. The channel info
152 CHAN2G(1, 2412, 0), 135 * is filled in after querying the device.
153 CHAN2G(2, 2417, 0), 136 */
154 CHAN2G(3, 2422, 0), 137static const struct ieee80211_supported_band __wl_band_2ghz = {
155 CHAN2G(4, 2427, 0),
156 CHAN2G(5, 2432, 0),
157 CHAN2G(6, 2437, 0),
158 CHAN2G(7, 2442, 0),
159 CHAN2G(8, 2447, 0),
160 CHAN2G(9, 2452, 0),
161 CHAN2G(10, 2457, 0),
162 CHAN2G(11, 2462, 0),
163 CHAN2G(12, 2467, 0),
164 CHAN2G(13, 2472, 0),
165 CHAN2G(14, 2484, 0),
166};
167
168static struct ieee80211_channel __wl_5ghz_a_channels[] = {
169 CHAN5G(34, 0), CHAN5G(36, 0),
170 CHAN5G(38, 0), CHAN5G(40, 0),
171 CHAN5G(42, 0), CHAN5G(44, 0),
172 CHAN5G(46, 0), CHAN5G(48, 0),
173 CHAN5G(52, 0), CHAN5G(56, 0),
174 CHAN5G(60, 0), CHAN5G(64, 0),
175 CHAN5G(100, 0), CHAN5G(104, 0),
176 CHAN5G(108, 0), CHAN5G(112, 0),
177 CHAN5G(116, 0), CHAN5G(120, 0),
178 CHAN5G(124, 0), CHAN5G(128, 0),
179 CHAN5G(132, 0), CHAN5G(136, 0),
180 CHAN5G(140, 0), CHAN5G(149, 0),
181 CHAN5G(153, 0), CHAN5G(157, 0),
182 CHAN5G(161, 0), CHAN5G(165, 0),
183 CHAN5G(184, 0), CHAN5G(188, 0),
184 CHAN5G(192, 0), CHAN5G(196, 0),
185 CHAN5G(200, 0), CHAN5G(204, 0),
186 CHAN5G(208, 0), CHAN5G(212, 0),
187 CHAN5G(216, 0),
188};
189
190static struct ieee80211_supported_band __wl_band_2ghz = {
191 .band = IEEE80211_BAND_2GHZ, 138 .band = IEEE80211_BAND_2GHZ,
192 .channels = __wl_2ghz_channels,
193 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
194 .bitrates = wl_g_rates, 139 .bitrates = wl_g_rates,
195 .n_bitrates = wl_g_rates_size, 140 .n_bitrates = wl_g_rates_size,
196 .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
197}; 141};
198 142
199static struct ieee80211_supported_band __wl_band_5ghz_a = { 143static const struct ieee80211_supported_band __wl_band_5ghz_a = {
200 .band = IEEE80211_BAND_5GHZ, 144 .band = IEEE80211_BAND_5GHZ,
201 .channels = __wl_5ghz_a_channels,
202 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
203 .bitrates = wl_a_rates, 145 .bitrates = wl_a_rates,
204 .n_bitrates = wl_a_rates_size, 146 .n_bitrates = wl_a_rates_size,
205}; 147};
@@ -592,7 +534,7 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
592 534
593static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc) 535static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
594{ 536{
595 if ((brcmf_get_chip_info(ifp) >> 4) == 0x4329) 537 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
596 brcmf_set_mpc(ifp, mpc); 538 brcmf_set_mpc(ifp, mpc);
597} 539}
598 540
@@ -1619,17 +1561,10 @@ static
1619enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp, 1561enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1620 enum nl80211_auth_type type) 1562 enum nl80211_auth_type type)
1621{ 1563{
1622 u32 ci; 1564 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1623 if (type == NL80211_AUTHTYPE_AUTOMATIC) { 1565 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1624 /* shift to ignore chip revision */ 1566 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1625 ci = brcmf_get_chip_info(ifp) >> 4; 1567 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1626 switch (ci) {
1627 case 43236:
1628 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1629 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1630 default:
1631 break;
1632 }
1633 } 1568 }
1634 return type; 1569 return type;
1635} 1570}
@@ -4284,122 +4219,6 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4284 .tdls_oper = brcmf_cfg80211_tdls_oper, 4219 .tdls_oper = brcmf_cfg80211_tdls_oper,
4285}; 4220};
4286 4221
4287static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4288{
4289 /* scheduled scan settings */
4290 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4291 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4292 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4293 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4294}
4295
4296static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4297 {
4298 .max = 2,
4299 .types = BIT(NL80211_IFTYPE_STATION) |
4300 BIT(NL80211_IFTYPE_ADHOC) |
4301 BIT(NL80211_IFTYPE_AP)
4302 },
4303 {
4304 .max = 1,
4305 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4306 BIT(NL80211_IFTYPE_P2P_GO)
4307 },
4308 {
4309 .max = 1,
4310 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4311 }
4312};
4313static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4314 {
4315 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4316 .num_different_channels = 2,
4317 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4318 .limits = brcmf_iface_limits
4319 }
4320};
4321
4322static const struct ieee80211_txrx_stypes
4323brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4324 [NL80211_IFTYPE_STATION] = {
4325 .tx = 0xffff,
4326 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4327 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4328 },
4329 [NL80211_IFTYPE_P2P_CLIENT] = {
4330 .tx = 0xffff,
4331 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4332 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4333 },
4334 [NL80211_IFTYPE_P2P_GO] = {
4335 .tx = 0xffff,
4336 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4337 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4338 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4339 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4340 BIT(IEEE80211_STYPE_AUTH >> 4) |
4341 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4342 BIT(IEEE80211_STYPE_ACTION >> 4)
4343 },
4344 [NL80211_IFTYPE_P2P_DEVICE] = {
4345 .tx = 0xffff,
4346 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4347 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4348 }
4349};
4350
4351static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4352{
4353 struct wiphy *wiphy;
4354 s32 err = 0;
4355
4356 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4357 if (!wiphy) {
4358 brcmf_err("Could not allocate wiphy device\n");
4359 return ERR_PTR(-ENOMEM);
4360 }
4361 set_wiphy_dev(wiphy, phydev);
4362 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4363 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4364 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4365 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4366 BIT(NL80211_IFTYPE_ADHOC) |
4367 BIT(NL80211_IFTYPE_AP) |
4368 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4369 BIT(NL80211_IFTYPE_P2P_GO) |
4370 BIT(NL80211_IFTYPE_P2P_DEVICE);
4371 wiphy->iface_combinations = brcmf_iface_combos;
4372 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4373 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4374 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4375 wiphy->cipher_suites = __wl_cipher_suites;
4376 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4377 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4378 WIPHY_FLAG_OFFCHAN_TX |
4379 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4380 WIPHY_FLAG_SUPPORTS_TDLS;
4381 if (!brcmf_roamoff)
4382 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4383 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4384 wiphy->max_remain_on_channel_duration = 5000;
4385 brcmf_wiphy_pno_params(wiphy);
4386 brcmf_dbg(INFO, "Registering custom regulatory\n");
4387 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4388 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4389
4390 /* vendor commands/events support */
4391 wiphy->vendor_commands = brcmf_vendor_cmds;
4392 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
4393
4394 err = wiphy_register(wiphy);
4395 if (err < 0) {
4396 brcmf_err("Could not register wiphy device (%d)\n", err);
4397 wiphy_free(wiphy);
4398 return ERR_PTR(err);
4399 }
4400 return wiphy;
4401}
4402
4403struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, 4222struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4404 enum nl80211_iftype type, 4223 enum nl80211_iftype type,
4405 bool pm_block) 4224 bool pm_block)
@@ -4943,138 +4762,6 @@ static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4943 mutex_init(&event->vif_event_lock); 4762 mutex_init(&event->vif_event_lock);
4944} 4763}
4945 4764
4946static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
4947{
4948 struct brcmf_fil_bwcap_le band_bwcap;
4949 u32 val;
4950 int err;
4951
4952 /* verify support for bw_cap command */
4953 val = WLC_BAND_5G;
4954 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
4955
4956 if (!err) {
4957 /* only set 2G bandwidth using bw_cap command */
4958 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
4959 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
4960 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
4961 sizeof(band_bwcap));
4962 } else {
4963 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
4964 val = WLC_N_BW_40ALL;
4965 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
4966 }
4967 return err;
4968}
4969
4970struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4971 struct device *busdev)
4972{
4973 struct net_device *ndev = drvr->iflist[0]->ndev;
4974 struct brcmf_cfg80211_info *cfg;
4975 struct wiphy *wiphy;
4976 struct brcmf_cfg80211_vif *vif;
4977 struct brcmf_if *ifp;
4978 s32 err = 0;
4979 s32 io_type;
4980
4981 if (!ndev) {
4982 brcmf_err("ndev is invalid\n");
4983 return NULL;
4984 }
4985
4986 ifp = netdev_priv(ndev);
4987 wiphy = brcmf_setup_wiphy(busdev);
4988 if (IS_ERR(wiphy))
4989 return NULL;
4990
4991 cfg = wiphy_priv(wiphy);
4992 cfg->wiphy = wiphy;
4993 cfg->pub = drvr;
4994 init_vif_event(&cfg->vif_event);
4995 INIT_LIST_HEAD(&cfg->vif_list);
4996
4997 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4998 if (IS_ERR(vif)) {
4999 wiphy_free(wiphy);
5000 return NULL;
5001 }
5002
5003 vif->ifp = ifp;
5004 vif->wdev.netdev = ndev;
5005 ndev->ieee80211_ptr = &vif->wdev;
5006 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
5007
5008 err = wl_init_priv(cfg);
5009 if (err) {
5010 brcmf_err("Failed to init iwm_priv (%d)\n", err);
5011 goto cfg80211_attach_out;
5012 }
5013 ifp->vif = vif;
5014
5015 err = brcmf_p2p_attach(cfg);
5016 if (err) {
5017 brcmf_err("P2P initilisation failed (%d)\n", err);
5018 goto cfg80211_p2p_attach_out;
5019 }
5020 err = brcmf_btcoex_attach(cfg);
5021 if (err) {
5022 brcmf_err("BT-coex initialisation failed (%d)\n", err);
5023 brcmf_p2p_detach(&cfg->p2p);
5024 goto cfg80211_p2p_attach_out;
5025 }
5026
5027 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5028 * setup 40MHz in 2GHz band and enable OBSS scanning.
5029 */
5030 if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
5031 IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
5032 err = brcmf_enable_bw40_2g(ifp);
5033 if (!err)
5034 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5035 BRCMF_OBSS_COEX_AUTO);
5036 }
5037 /* clear for now and rely on update later */
5038 wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.ht_supported = false;
5039 wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap = 0;
5040
5041 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5042 if (err) {
5043 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5044 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5045 }
5046
5047 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
5048 &io_type);
5049 if (err) {
5050 brcmf_err("Failed to get D11 version (%d)\n", err);
5051 goto cfg80211_p2p_attach_out;
5052 }
5053 cfg->d11inf.io_type = (u8)io_type;
5054 brcmu_d11_attach(&cfg->d11inf);
5055
5056 return cfg;
5057
5058cfg80211_p2p_attach_out:
5059 wl_deinit_priv(cfg);
5060
5061cfg80211_attach_out:
5062 brcmf_free_vif(vif);
5063 return NULL;
5064}
5065
5066void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5067{
5068 if (!cfg)
5069 return;
5070
5071 WARN_ON(!list_empty(&cfg->vif_list));
5072 wiphy_unregister(cfg->wiphy);
5073 brcmf_btcoex_detach(cfg);
5074 wl_deinit_priv(cfg);
5075 wiphy_free(cfg->wiphy);
5076}
5077
5078static s32 4765static s32
5079brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout) 4766brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5080{ 4767{
@@ -5167,25 +4854,77 @@ dongle_scantime_out:
5167 return err; 4854 return err;
5168} 4855}
5169 4856
4857/* Filter the list of channels received from firmware counting only
4858 * the 20MHz channels. The wiphy band data only needs those which get
4859 * flagged to indicate if they can take part in higher bandwidth.
4860 */
4861static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg,
4862 struct brcmf_chanspec_list *chlist,
4863 u32 chcnt[])
4864{
4865 u32 total = le32_to_cpu(chlist->count);
4866 struct brcmu_chan ch;
4867 int i;
4868
4869 for (i = 0; i <= total; i++) {
4870 ch.chspec = (u16)le32_to_cpu(chlist->element[i]);
4871 cfg->d11inf.decchspec(&ch);
4872
4873 /* Firmware gives a ordered list. We skip non-20MHz
4874 * channels is 2G. For 5G we can abort upon reaching
4875 * a non-20MHz channel in the list.
4876 */
4877 if (ch.bw != BRCMU_CHAN_BW_20) {
4878 if (ch.band == BRCMU_CHAN_BAND_5G)
4879 break;
4880 else
4881 continue;
4882 }
4883
4884 if (ch.band == BRCMU_CHAN_BAND_2G)
4885 chcnt[0] += 1;
4886 else if (ch.band == BRCMU_CHAN_BAND_5G)
4887 chcnt[1] += 1;
4888 }
4889}
4890
4891static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
4892 struct brcmu_chan *ch)
4893{
4894 u32 ht40_flag;
5170 4895
5171static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, 4896 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5172 u32 bw_cap[]) 4897 if (ch->sb == BRCMU_CHAN_SB_U) {
4898 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
4899 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
4900 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
4901 } else {
4902 /* It should be one of
4903 * IEEE80211_CHAN_NO_HT40 or
4904 * IEEE80211_CHAN_NO_HT40PLUS
4905 */
4906 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
4907 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
4908 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
4909 }
4910}
4911
4912static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
4913 u32 bw_cap[])
5173{ 4914{
5174 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 4915 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5175 struct ieee80211_channel *band_chan_arr; 4916 struct ieee80211_supported_band *band;
4917 struct ieee80211_channel *channel;
4918 struct wiphy *wiphy;
5176 struct brcmf_chanspec_list *list; 4919 struct brcmf_chanspec_list *list;
5177 struct brcmu_chan ch; 4920 struct brcmu_chan ch;
5178 s32 err; 4921 int err;
5179 u8 *pbuf; 4922 u8 *pbuf;
5180 u32 i, j; 4923 u32 i, j;
5181 u32 total; 4924 u32 total;
5182 enum ieee80211_band band; 4925 u32 chaninfo;
5183 u32 channel; 4926 u32 chcnt[2] = { 0, 0 };
5184 u32 *n_cnt;
5185 u32 index; 4927 u32 index;
5186 u32 ht40_flag;
5187 bool update;
5188 u32 array_size;
5189 4928
5190 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); 4929 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5191 4930
@@ -5198,11 +4937,45 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5198 BRCMF_DCMD_MEDLEN); 4937 BRCMF_DCMD_MEDLEN);
5199 if (err) { 4938 if (err) {
5200 brcmf_err("get chanspecs error (%d)\n", err); 4939 brcmf_err("get chanspecs error (%d)\n", err);
5201 goto exit; 4940 goto fail_pbuf;
5202 } 4941 }
5203 4942
5204 __wl_band_2ghz.n_channels = 0; 4943 brcmf_count_20mhz_channels(cfg, list, chcnt);
5205 __wl_band_5ghz_a.n_channels = 0; 4944 wiphy = cfg_to_wiphy(cfg);
4945 if (chcnt[0]) {
4946 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
4947 GFP_KERNEL);
4948 if (band == NULL) {
4949 err = -ENOMEM;
4950 goto fail_pbuf;
4951 }
4952 band->channels = kcalloc(chcnt[0], sizeof(*channel),
4953 GFP_KERNEL);
4954 if (band->channels == NULL) {
4955 kfree(band);
4956 err = -ENOMEM;
4957 goto fail_pbuf;
4958 }
4959 band->n_channels = 0;
4960 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
4961 }
4962 if (chcnt[1]) {
4963 band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a),
4964 GFP_KERNEL);
4965 if (band == NULL) {
4966 err = -ENOMEM;
4967 goto fail_band2g;
4968 }
4969 band->channels = kcalloc(chcnt[1], sizeof(*channel),
4970 GFP_KERNEL);
4971 if (band->channels == NULL) {
4972 kfree(band);
4973 err = -ENOMEM;
4974 goto fail_band2g;
4975 }
4976 band->n_channels = 0;
4977 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
4978 }
5206 4979
5207 total = le32_to_cpu(list->count); 4980 total = le32_to_cpu(list->count);
5208 for (i = 0; i < total; i++) { 4981 for (i = 0; i < total; i++) {
@@ -5210,100 +4983,151 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5210 cfg->d11inf.decchspec(&ch); 4983 cfg->d11inf.decchspec(&ch);
5211 4984
5212 if (ch.band == BRCMU_CHAN_BAND_2G) { 4985 if (ch.band == BRCMU_CHAN_BAND_2G) {
5213 band_chan_arr = __wl_2ghz_channels; 4986 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5214 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5215 n_cnt = &__wl_band_2ghz.n_channels;
5216 band = IEEE80211_BAND_2GHZ;
5217 } else if (ch.band == BRCMU_CHAN_BAND_5G) { 4987 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5218 band_chan_arr = __wl_5ghz_a_channels; 4988 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5219 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5220 n_cnt = &__wl_band_5ghz_a.n_channels;
5221 band = IEEE80211_BAND_5GHZ;
5222 } else { 4989 } else {
5223 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); 4990 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5224 continue; 4991 continue;
5225 } 4992 }
5226 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) && 4993 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5227 ch.bw == BRCMU_CHAN_BW_40) 4994 ch.bw == BRCMU_CHAN_BW_40)
5228 continue; 4995 continue;
5229 if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) && 4996 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5230 ch.bw == BRCMU_CHAN_BW_80) 4997 ch.bw == BRCMU_CHAN_BW_80)
5231 continue; 4998 continue;
5232 update = false; 4999
5233 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { 5000 channel = band->channels;
5234 if (band_chan_arr[j].hw_value == ch.chnum) { 5001 index = band->n_channels;
5235 update = true; 5002 for (j = 0; j < band->n_channels; j++) {
5003 if (channel[j].hw_value == ch.chnum) {
5004 index = j;
5236 break; 5005 break;
5237 } 5006 }
5238 } 5007 }
5239 if (update) 5008 channel[index].center_freq =
5240 index = j; 5009 ieee80211_channel_to_frequency(ch.chnum, band->band);
5241 else 5010 channel[index].hw_value = ch.chnum;
5242 index = *n_cnt; 5011
5243 if (index < array_size) { 5012 /* assuming the chanspecs order is HT20,
5244 band_chan_arr[index].center_freq = 5013 * HT40 upper, HT40 lower, and VHT80.
5245 ieee80211_channel_to_frequency(ch.chnum, band); 5014 */
5246 band_chan_arr[index].hw_value = ch.chnum; 5015 if (ch.bw == BRCMU_CHAN_BW_80) {
5247 5016 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5248 /* assuming the chanspecs order is HT20, 5017 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5249 * HT40 upper, HT40 lower, and VHT80. 5018 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5019 } else {
5020 /* disable other bandwidths for now as mentioned
5021 * order assure they are enabled for subsequent
5022 * chanspecs.
5250 */ 5023 */
5251 if (ch.bw == BRCMU_CHAN_BW_80) { 5024 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5252 band_chan_arr[index].flags &= 5025 IEEE80211_CHAN_NO_80MHZ;
5253 ~IEEE80211_CHAN_NO_80MHZ; 5026 ch.bw = BRCMU_CHAN_BW_20;
5254 } else if (ch.bw == BRCMU_CHAN_BW_40) { 5027 cfg->d11inf.encchspec(&ch);
5255 ht40_flag = band_chan_arr[index].flags & 5028 chaninfo = ch.chspec;
5256 IEEE80211_CHAN_NO_HT40; 5029 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5257 if (ch.sb == BRCMU_CHAN_SB_U) { 5030 &chaninfo);
5258 if (ht40_flag == IEEE80211_CHAN_NO_HT40) 5031 if (!err) {
5259 band_chan_arr[index].flags &= 5032 if (chaninfo & WL_CHAN_RADAR)
5260 ~IEEE80211_CHAN_NO_HT40; 5033 channel[index].flags |=
5261 band_chan_arr[index].flags |= 5034 (IEEE80211_CHAN_RADAR |
5262 IEEE80211_CHAN_NO_HT40PLUS; 5035 IEEE80211_CHAN_NO_IR);
5263 } else { 5036 if (chaninfo & WL_CHAN_PASSIVE)
5264 /* It should be one of 5037 channel[index].flags |=
5265 * IEEE80211_CHAN_NO_HT40 or 5038 IEEE80211_CHAN_NO_IR;
5266 * IEEE80211_CHAN_NO_HT40PLUS
5267 */
5268 band_chan_arr[index].flags &=
5269 ~IEEE80211_CHAN_NO_HT40;
5270 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5271 band_chan_arr[index].flags |=
5272 IEEE80211_CHAN_NO_HT40MINUS;
5273 }
5274 } else {
5275 /* disable other bandwidths for now as mentioned
5276 * order assure they are enabled for subsequent
5277 * chanspecs.
5278 */
5279 band_chan_arr[index].flags =
5280 IEEE80211_CHAN_NO_HT40 |
5281 IEEE80211_CHAN_NO_80MHZ;
5282 ch.bw = BRCMU_CHAN_BW_20;
5283 cfg->d11inf.encchspec(&ch);
5284 channel = ch.chspec;
5285 err = brcmf_fil_bsscfg_int_get(ifp,
5286 "per_chan_info",
5287 &channel);
5288 if (!err) {
5289 if (channel & WL_CHAN_RADAR)
5290 band_chan_arr[index].flags |=
5291 (IEEE80211_CHAN_RADAR |
5292 IEEE80211_CHAN_NO_IR);
5293 if (channel & WL_CHAN_PASSIVE)
5294 band_chan_arr[index].flags |=
5295 IEEE80211_CHAN_NO_IR;
5296 }
5297 } 5039 }
5298 if (!update)
5299 (*n_cnt)++;
5300 } 5040 }
5041 if (index == band->n_channels)
5042 band->n_channels++;
5301 } 5043 }
5302exit: 5044 kfree(pbuf);
5045 return 0;
5046
5047fail_band2g:
5048 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
5049 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
5050 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
5051fail_pbuf:
5303 kfree(pbuf); 5052 kfree(pbuf);
5304 return err; 5053 return err;
5305} 5054}
5306 5055
5056static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5057{
5058 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5059 struct ieee80211_supported_band *band;
5060 struct brcmf_fil_bwcap_le band_bwcap;
5061 struct brcmf_chanspec_list *list;
5062 u8 *pbuf;
5063 u32 val;
5064 int err;
5065 struct brcmu_chan ch;
5066 u32 num_chan;
5067 int i, j;
5068
5069 /* verify support for bw_cap command */
5070 val = WLC_BAND_5G;
5071 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5072
5073 if (!err) {
5074 /* only set 2G bandwidth using bw_cap command */
5075 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5076 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5077 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5078 sizeof(band_bwcap));
5079 } else {
5080 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5081 val = WLC_N_BW_40ALL;
5082 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5083 }
5084
5085 if (!err) {
5086 /* update channel info in 2G band */
5087 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5088
5089 if (pbuf == NULL)
5090 return -ENOMEM;
5091
5092 ch.band = BRCMU_CHAN_BAND_2G;
5093 ch.bw = BRCMU_CHAN_BW_40;
5094 ch.chnum = 0;
5095 cfg->d11inf.encchspec(&ch);
5096
5097 /* pass encoded chanspec in query */
5098 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5099
5100 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5101 BRCMF_DCMD_MEDLEN);
5102 if (err) {
5103 brcmf_err("get chanspecs error (%d)\n", err);
5104 kfree(pbuf);
5105 return err;
5106 }
5107
5108 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5109 list = (struct brcmf_chanspec_list *)pbuf;
5110 num_chan = le32_to_cpu(list->count);
5111 for (i = 0; i < num_chan; i++) {
5112 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5113 cfg->d11inf.decchspec(&ch);
5114 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5115 continue;
5116 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5117 continue;
5118 for (j = 0; j < band->n_channels; j++) {
5119 if (band->channels[j].hw_value == ch.chnum)
5120 break;
5121 }
5122 if (WARN_ON(j == band->n_channels))
5123 continue;
5124
5125 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5126 }
5127 }
5128 return err;
5129}
5130
5307static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) 5131static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5308{ 5132{
5309 u32 band, mimo_bwcap; 5133 u32 band, mimo_bwcap;
@@ -5394,44 +5218,19 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5394 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map; 5218 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5395} 5219}
5396 5220
5397static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) 5221static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5398{ 5222{
5223 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5399 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 5224 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5400 struct wiphy *wiphy;
5401 s32 phy_list;
5402 u32 band_list[3];
5403 u32 nmode = 0; 5225 u32 nmode = 0;
5404 u32 vhtmode = 0; 5226 u32 vhtmode = 0;
5405 u32 bw_cap[2] = { 0, 0 }; 5227 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5406 u32 rxchain; 5228 u32 rxchain;
5407 u32 nchain; 5229 u32 nchain;
5408 s8 phy; 5230 int err;
5409 s32 err;
5410 u32 nband;
5411 s32 i; 5231 s32 i;
5412 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5413 struct ieee80211_supported_band *band; 5232 struct ieee80211_supported_band *band;
5414 5233
5415 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5416 &phy_list, sizeof(phy_list));
5417 if (err) {
5418 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5419 return err;
5420 }
5421
5422 phy = ((char *)&phy_list)[0];
5423 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5424
5425
5426 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5427 &band_list, sizeof(band_list));
5428 if (err) {
5429 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5430 return err;
5431 }
5432 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5433 band_list[0], band_list[1], band_list[2]);
5434
5435 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode); 5234 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5436 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); 5235 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5437 if (err) { 5236 if (err) {
@@ -5453,44 +5252,129 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5453 } 5252 }
5454 brcmf_dbg(INFO, "nchain=%d\n", nchain); 5253 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5455 5254
5456 err = brcmf_construct_reginfo(cfg, bw_cap); 5255 err = brcmf_construct_chaninfo(cfg, bw_cap);
5457 if (err) { 5256 if (err) {
5458 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err); 5257 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5459 return err; 5258 return err;
5460 } 5259 }
5461 5260
5462 nband = band_list[0]; 5261 wiphy = cfg_to_wiphy(cfg);
5463 5262 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5464 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { 5263 band = wiphy->bands[i];
5465 band = NULL; 5264 if (band == NULL)
5466 if ((band_list[i] == WLC_BAND_5G) &&
5467 (__wl_band_5ghz_a.n_channels > 0))
5468 band = &__wl_band_5ghz_a;
5469 else if ((band_list[i] == WLC_BAND_2G) &&
5470 (__wl_band_2ghz.n_channels > 0))
5471 band = &__wl_band_2ghz;
5472 else
5473 continue; 5265 continue;
5474 5266
5475 if (nmode) 5267 if (nmode)
5476 brcmf_update_ht_cap(band, bw_cap, nchain); 5268 brcmf_update_ht_cap(band, bw_cap, nchain);
5477 if (vhtmode) 5269 if (vhtmode)
5478 brcmf_update_vht_cap(band, bw_cap, nchain); 5270 brcmf_update_vht_cap(band, bw_cap, nchain);
5479 bands[band->band] = band;
5480 } 5271 }
5481 5272
5482 wiphy = cfg_to_wiphy(cfg); 5273 return 0;
5483 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5484 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5485 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5486
5487 return err;
5488} 5274}
5489 5275
5276static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
5277 {
5278 .max = 2,
5279 .types = BIT(NL80211_IFTYPE_STATION) |
5280 BIT(NL80211_IFTYPE_ADHOC) |
5281 BIT(NL80211_IFTYPE_AP)
5282 },
5283 {
5284 .max = 1,
5285 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5286 BIT(NL80211_IFTYPE_P2P_GO)
5287 },
5288 {
5289 .max = 1,
5290 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
5291 }
5292};
5293static struct ieee80211_iface_combination brcmf_iface_combos[] = {
5294 {
5295 .max_interfaces = BRCMF_IFACE_MAX_CNT,
5296 .num_different_channels = 1,
5297 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
5298 .limits = brcmf_iface_limits
5299 }
5300};
5301
5302static const struct ieee80211_txrx_stypes
5303brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5304 [NL80211_IFTYPE_STATION] = {
5305 .tx = 0xffff,
5306 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5307 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5308 },
5309 [NL80211_IFTYPE_P2P_CLIENT] = {
5310 .tx = 0xffff,
5311 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5312 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5313 },
5314 [NL80211_IFTYPE_P2P_GO] = {
5315 .tx = 0xffff,
5316 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5317 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5318 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5319 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5320 BIT(IEEE80211_STYPE_AUTH >> 4) |
5321 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5322 BIT(IEEE80211_STYPE_ACTION >> 4)
5323 },
5324 [NL80211_IFTYPE_P2P_DEVICE] = {
5325 .tx = 0xffff,
5326 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5327 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5328 }
5329};
5490 5330
5491static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg) 5331static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5492{ 5332{
5493 return brcmf_update_wiphybands(cfg); 5333 /* scheduled scan settings */
5334 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5335 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5336 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5337 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5338}
5339
5340static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5341{
5342 struct ieee80211_iface_combination ifc_combo;
5343 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5344 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5345 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5346 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5347 BIT(NL80211_IFTYPE_ADHOC) |
5348 BIT(NL80211_IFTYPE_AP) |
5349 BIT(NL80211_IFTYPE_P2P_CLIENT) |
5350 BIT(NL80211_IFTYPE_P2P_GO) |
5351 BIT(NL80211_IFTYPE_P2P_DEVICE);
5352 /* need VSDB firmware feature for concurrent channels */
5353 ifc_combo = brcmf_iface_combos[0];
5354 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5355 ifc_combo.num_different_channels = 2;
5356 wiphy->iface_combinations = kmemdup(&ifc_combo,
5357 sizeof(ifc_combo),
5358 GFP_KERNEL);
5359 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
5360 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5361 wiphy->cipher_suites = __wl_cipher_suites;
5362 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5363 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5364 WIPHY_FLAG_OFFCHAN_TX |
5365 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5366 WIPHY_FLAG_SUPPORTS_TDLS;
5367 if (!brcmf_roamoff)
5368 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5369 wiphy->mgmt_stypes = brcmf_txrx_stypes;
5370 wiphy->max_remain_on_channel_duration = 5000;
5371 brcmf_wiphy_pno_params(wiphy);
5372
5373 /* vendor commands/events support */
5374 wiphy->vendor_commands = brcmf_vendor_cmds;
5375 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5376
5377 return brcmf_setup_wiphybands(wiphy);
5494} 5378}
5495 5379
5496static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) 5380static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
@@ -5528,9 +5412,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5528 NULL, NULL); 5412 NULL, NULL);
5529 if (err) 5413 if (err)
5530 goto default_conf_out; 5414 goto default_conf_out;
5531 err = brcmf_dongle_probecap(cfg);
5532 if (err)
5533 goto default_conf_out;
5534 5415
5535 brcmf_configure_arp_offload(ifp, true); 5416 brcmf_configure_arp_offload(ifp, true);
5536 5417
@@ -5658,3 +5539,150 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5658 vif_event_equals(event, action), timeout); 5539 vif_event_equals(event, action), timeout);
5659} 5540}
5660 5541
5542static void brcmf_free_wiphy(struct wiphy *wiphy)
5543{
5544 kfree(wiphy->iface_combinations);
5545 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
5546 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
5547 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
5548 }
5549 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
5550 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
5551 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
5552 }
5553 wiphy_free(wiphy);
5554}
5555
5556struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5557 struct device *busdev)
5558{
5559 struct net_device *ndev = drvr->iflist[0]->ndev;
5560 struct brcmf_cfg80211_info *cfg;
5561 struct wiphy *wiphy;
5562 struct brcmf_cfg80211_vif *vif;
5563 struct brcmf_if *ifp;
5564 s32 err = 0;
5565 s32 io_type;
5566 u16 *cap = NULL;
5567
5568 if (!ndev) {
5569 brcmf_err("ndev is invalid\n");
5570 return NULL;
5571 }
5572
5573 ifp = netdev_priv(ndev);
5574 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
5575 if (!wiphy) {
5576 brcmf_err("Could not allocate wiphy device\n");
5577 return NULL;
5578 }
5579 set_wiphy_dev(wiphy, busdev);
5580
5581 cfg = wiphy_priv(wiphy);
5582 cfg->wiphy = wiphy;
5583 cfg->pub = drvr;
5584 init_vif_event(&cfg->vif_event);
5585 INIT_LIST_HEAD(&cfg->vif_list);
5586
5587 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
5588 if (IS_ERR(vif))
5589 goto wiphy_out;
5590
5591 vif->ifp = ifp;
5592 vif->wdev.netdev = ndev;
5593 ndev->ieee80211_ptr = &vif->wdev;
5594 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
5595
5596 err = wl_init_priv(cfg);
5597 if (err) {
5598 brcmf_err("Failed to init iwm_priv (%d)\n", err);
5599 brcmf_free_vif(vif);
5600 goto wiphy_out;
5601 }
5602 ifp->vif = vif;
5603
5604 /* determine d11 io type before wiphy setup */
5605 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
5606 if (err) {
5607 brcmf_err("Failed to get D11 version (%d)\n", err);
5608 goto priv_out;
5609 }
5610 cfg->d11inf.io_type = (u8)io_type;
5611 brcmu_d11_attach(&cfg->d11inf);
5612
5613 err = brcmf_setup_wiphy(wiphy, ifp);
5614 if (err < 0)
5615 goto priv_out;
5616
5617 brcmf_dbg(INFO, "Registering custom regulatory\n");
5618 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
5619 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5620
5621 /* firmware defaults to 40MHz disabled in 2G band. We signal
5622 * cfg80211 here that we do and have it decide we can enable
5623 * it. But first check if device does support 2G operation.
5624 */
5625 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
5626 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
5627 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5628 }
5629 err = wiphy_register(wiphy);
5630 if (err < 0) {
5631 brcmf_err("Could not register wiphy device (%d)\n", err);
5632 goto priv_out;
5633 }
5634
5635 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5636 * setup 40MHz in 2GHz band and enable OBSS scanning.
5637 */
5638 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
5639 err = brcmf_enable_bw40_2g(cfg);
5640 if (!err)
5641 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5642 BRCMF_OBSS_COEX_AUTO);
5643 else
5644 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5645 }
5646
5647 err = brcmf_p2p_attach(cfg);
5648 if (err) {
5649 brcmf_err("P2P initilisation failed (%d)\n", err);
5650 goto wiphy_unreg_out;
5651 }
5652 err = brcmf_btcoex_attach(cfg);
5653 if (err) {
5654 brcmf_err("BT-coex initialisation failed (%d)\n", err);
5655 brcmf_p2p_detach(&cfg->p2p);
5656 goto wiphy_unreg_out;
5657 }
5658
5659 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5660 if (err) {
5661 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5662 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5663 }
5664
5665 return cfg;
5666
5667wiphy_unreg_out:
5668 wiphy_unregister(cfg->wiphy);
5669priv_out:
5670 wl_deinit_priv(cfg);
5671 brcmf_free_vif(vif);
5672wiphy_out:
5673 brcmf_free_wiphy(wiphy);
5674 return NULL;
5675}
5676
5677void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5678{
5679 if (!cfg)
5680 return;
5681
5682 WARN_ON(!list_empty(&cfg->vif_list));
5683 wiphy_unregister(cfg->wiphy);
5684 brcmf_btcoex_detach(cfg);
5685 brcmf_p2p_detach(&cfg->p2p);
5686 wl_deinit_priv(cfg);
5687 brcmf_free_wiphy(cfg->wiphy);
5688}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index af8ba64ace39..1b474828d5b8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4707,41 +4707,6 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4707 return err; 4707 return err;
4708} 4708}
4709 4709
4710static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
4711{
4712 uint unit;
4713 unit = wlc->pub->unit;
4714
4715 if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
4716 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
4717 wlc->band->antgain = 8;
4718 } else if (wlc->band->antgain == -1) {
4719 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
4720 " srom, using 2dB\n", unit, __func__);
4721 wlc->band->antgain = 8;
4722 } else {
4723 s8 gain, fract;
4724 /* Older sroms specified gain in whole dbm only. In order
4725 * be able to specify qdbm granularity and remain backward
4726 * compatible the whole dbms are now encoded in only
4727 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
4728 * 6 bit signed number ranges from -32 - 31.
4729 *
4730 * Examples:
4731 * 0x1 = 1 db,
4732 * 0xc1 = 1.75 db (1 + 3 quarters),
4733 * 0x3f = -1 (-1 + 0 quarters),
4734 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
4735 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
4736 */
4737 gain = wlc->band->antgain & 0x3f;
4738 gain <<= 2; /* Sign extend */
4739 gain >>= 2;
4740 fract = (wlc->band->antgain & 0xc0) >> 6;
4741 wlc->band->antgain = 4 * gain + fract;
4742 }
4743}
4744
4745static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) 4710static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4746{ 4711{
4747 int aa; 4712 int aa;
@@ -4780,8 +4745,6 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4780 else 4745 else
4781 wlc->band->antgain = sprom->antenna_gain.a0; 4746 wlc->band->antgain = sprom->antenna_gain.a0;
4782 4747
4783 brcms_c_attach_antgain_init(wlc);
4784
4785 return true; 4748 return true;
4786} 4749}
4787 4750
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index d816270db3be..64d1a7ba040c 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -17,32 +17,56 @@
17#ifndef _BRCM_HW_IDS_H_ 17#ifndef _BRCM_HW_IDS_H_
18#define _BRCM_HW_IDS_H_ 18#define _BRCM_HW_IDS_H_
19 19
20#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ 20#include <linux/pci_ids.h>
21#include <linux/mmc/sdio_ids.h>
22
23#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
24#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
25#define BRCM_SDIO_VENDOR_ID_BROADCOM SDIO_VENDOR_ID_BROADCOM
26
27/* Chipcommon Core Chip IDs */
28#define BRCM_CC_43143_CHIP_ID 43143
29#define BRCM_CC_43235_CHIP_ID 43235
30#define BRCM_CC_43236_CHIP_ID 43236
31#define BRCM_CC_43238_CHIP_ID 43238
32#define BRCM_CC_43241_CHIP_ID 0x4324
33#define BRCM_CC_43242_CHIP_ID 43242
34#define BRCM_CC_4329_CHIP_ID 0x4329
35#define BRCM_CC_4330_CHIP_ID 0x4330
36#define BRCM_CC_4334_CHIP_ID 0x4334
37#define BRCM_CC_43362_CHIP_ID 43362
38#define BRCM_CC_4335_CHIP_ID 0x4335
39#define BRCM_CC_4339_CHIP_ID 0x4339
40#define BRCM_CC_4354_CHIP_ID 0x4354
41#define BRCM_CC_43566_CHIP_ID 43566
42#define BRCM_CC_43569_CHIP_ID 43569
43
44/* SDIO Device IDs */
45#define BRCM_SDIO_43143_DEVICE_ID BRCM_CC_43143_CHIP_ID
46#define BRCM_SDIO_43241_DEVICE_ID BRCM_CC_43241_CHIP_ID
47#define BRCM_SDIO_4329_DEVICE_ID BRCM_CC_4329_CHIP_ID
48#define BRCM_SDIO_4330_DEVICE_ID BRCM_CC_4330_CHIP_ID
49#define BRCM_SDIO_4334_DEVICE_ID BRCM_CC_4334_CHIP_ID
50#define BRCM_SDIO_43362_DEVICE_ID BRCM_CC_43362_CHIP_ID
51#define BRCM_SDIO_4335_4339_DEVICE_ID BRCM_CC_4335_CHIP_ID
52#define BRCM_SDIO_4354_DEVICE_ID BRCM_CC_4354_CHIP_ID
21 53
54/* USB Device IDs */
55#define BRCM_USB_43143_DEVICE_ID 0xbd1e
56#define BRCM_USB_43236_DEVICE_ID 0xbd17
57#define BRCM_USB_43242_DEVICE_ID 0xbd1f
58#define BRCM_USB_43569_DEVICE_ID 0xbd27
59#define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc
60
61/* brcmsmac IDs */
62#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
22#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ 63#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
23#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */ 64#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
24
25#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ 65#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
26
27#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ 66#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
28#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ 67#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
29 68
30/* Chipcommon Core Chip IDs */
31#define BCM4313_CHIP_ID 0x4313 69#define BCM4313_CHIP_ID 0x4313
32#define BCM43143_CHIP_ID 43143
33#define BCM43224_CHIP_ID 43224 70#define BCM43224_CHIP_ID 43224
34#define BCM43225_CHIP_ID 43225
35#define BCM43235_CHIP_ID 43235
36#define BCM43236_CHIP_ID 43236
37#define BCM43238_CHIP_ID 43238
38#define BCM43241_CHIP_ID 0x4324
39#define BCM4329_CHIP_ID 0x4329
40#define BCM4330_CHIP_ID 0x4330
41#define BCM4331_CHIP_ID 0x4331
42#define BCM4334_CHIP_ID 0x4334
43#define BCM4335_CHIP_ID 0x4335
44#define BCM43362_CHIP_ID 43362
45#define BCM4339_CHIP_ID 0x4339
46#define BCM4354_CHIP_ID 0x4354
47 71
48#endif /* _BRCM_HW_IDS_H_ */ 72#endif /* _BRCM_HW_IDS_H_ */