aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c51
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/btcoex.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bus.h (renamed from drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h)11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c (renamed from drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c)91
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h (renamed from drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h)9
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/common.c168
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/commonring.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c (renamed from drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c)8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.h (renamed from drivers/net/wireless/brcm80211/brcmfmac/dhd.h)7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/debug.c (renamed from drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c)6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/debug.h (renamed from drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h)6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c400
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c84
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h89
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c9
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/of.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c (renamed from drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c)80
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.h (renamed from drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h)8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c15
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c142
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h75
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/vendor.c6
33 files changed, 673 insertions, 672 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 90a977fe9a64..dc4c75083085 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -23,15 +23,15 @@ ccflags-y += -D__CHECK_ENDIAN__
23 23
24obj-$(CONFIG_BRCMFMAC) += brcmfmac.o 24obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
25brcmfmac-objs += \ 25brcmfmac-objs += \
26 wl_cfg80211.o \ 26 cfg80211.o \
27 chip.o \ 27 chip.o \
28 fwil.o \ 28 fwil.o \
29 fweh.o \ 29 fweh.o \
30 fwsignal.o \ 30 fwsignal.o \
31 p2p.o \ 31 p2p.o \
32 proto.o \ 32 proto.o \
33 dhd_common.o \ 33 common.o \
34 dhd_linux.o \ 34 core.o \
35 firmware.o \ 35 firmware.o \
36 feature.o \ 36 feature.o \
37 btcoex.o \ 37 btcoex.o \
@@ -43,14 +43,14 @@ brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \
43 flowring.o \ 43 flowring.o \
44 msgbuf.o 44 msgbuf.o
45brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ 45brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
46 dhd_sdio.o \ 46 sdio.o \
47 bcmsdh.o 47 bcmsdh.o
48brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ 48brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
49 usb.o 49 usb.o
50brcmfmac-$(CONFIG_BRCMFMAC_PCIE) += \ 50brcmfmac-$(CONFIG_BRCMFMAC_PCIE) += \
51 pcie.o 51 pcie.o
52brcmfmac-$(CONFIG_BRCMDBG) += \ 52brcmfmac-$(CONFIG_BRCMDBG) += \
53 dhd_dbg.o 53 debug.o
54brcmfmac-$(CONFIG_BRCM_TRACING) += \ 54brcmfmac-$(CONFIG_BRCM_TRACING) += \
55 tracepoint.o 55 tracepoint.o
56brcmfmac-$(CONFIG_OF) += \ 56brcmfmac-$(CONFIG_OF) += \
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
index a159ff3427de..8e0e91c4a0b1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -25,10 +25,10 @@
25#include <brcmu_utils.h> 25#include <brcmu_utils.h>
26#include <brcmu_wifi.h> 26#include <brcmu_wifi.h>
27 27
28#include "dhd.h" 28#include "core.h"
29#include "dhd_bus.h" 29#include "bus.h"
30#include "fwsignal.h" 30#include "fwsignal.h"
31#include "dhd_dbg.h" 31#include "debug.h"
32#include "tracepoint.h" 32#include "tracepoint.h"
33#include "proto.h" 33#include "proto.h"
34#include "bcdc.h" 34#include "bcdc.h"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 8dbd5dbb78fd..f754ffcd0308 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -41,9 +41,9 @@
41#include <chipcommon.h> 41#include <chipcommon.h>
42#include <soc.h> 42#include <soc.h>
43#include "chip.h" 43#include "chip.h"
44#include "dhd_bus.h" 44#include "bus.h"
45#include "dhd_dbg.h" 45#include "debug.h"
46#include "sdio_host.h" 46#include "sdio.h"
47#include "of.h" 47#include "of.h"
48 48
49#define SDIOH_API_ACCESS_RETRY_LIMIT 2 49#define SDIOH_API_ACCESS_RETRY_LIMIT 2
@@ -1064,6 +1064,16 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1064 if (!sdiodev->pdata) 1064 if (!sdiodev->pdata)
1065 brcmf_of_probe(sdiodev); 1065 brcmf_of_probe(sdiodev);
1066 1066
1067#ifdef CONFIG_PM_SLEEP
1068 /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
1069 * is true or when platform data OOB irq is true).
1070 */
1071 if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
1072 ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
1073 (sdiodev->pdata->oob_irq_supported)))
1074 bus_if->wowl_supported = true;
1075#endif
1076
1067 atomic_set(&sdiodev->suspend, false); 1077 atomic_set(&sdiodev->suspend, false);
1068 init_waitqueue_head(&sdiodev->request_word_wait); 1078 init_waitqueue_head(&sdiodev->request_word_wait);
1069 init_waitqueue_head(&sdiodev->request_buffer_wait); 1079 init_waitqueue_head(&sdiodev->request_buffer_wait);
@@ -1116,34 +1126,39 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
1116 brcmf_dbg(SDIO, "Exit\n"); 1126 brcmf_dbg(SDIO, "Exit\n");
1117} 1127}
1118 1128
1129void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1130{
1131 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1132 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1133
1134 brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
1135 sdiodev->wowl_enabled = enabled;
1136}
1137
1119#ifdef CONFIG_PM_SLEEP 1138#ifdef CONFIG_PM_SLEEP
1120static int brcmf_ops_sdio_suspend(struct device *dev) 1139static int brcmf_ops_sdio_suspend(struct device *dev)
1121{ 1140{
1122 mmc_pm_flag_t sdio_flags;
1123 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1141 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1124 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1142 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1125 int ret = 0; 1143 mmc_pm_flag_t sdio_flags;
1126 1144
1127 brcmf_dbg(SDIO, "Enter\n"); 1145 brcmf_dbg(SDIO, "Enter\n");
1128 1146
1129 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
1130 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
1131 brcmf_err("Host can't keep power while suspended\n");
1132 return -EINVAL;
1133 }
1134
1135 atomic_set(&sdiodev->suspend, true); 1147 atomic_set(&sdiodev->suspend, true);
1136 1148
1137 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); 1149 if (sdiodev->wowl_enabled) {
1138 if (ret) { 1150 sdio_flags = MMC_PM_KEEP_POWER;
1139 brcmf_err("Failed to set pm_flags\n"); 1151 if (sdiodev->pdata->oob_irq_supported)
1140 atomic_set(&sdiodev->suspend, false); 1152 enable_irq_wake(sdiodev->pdata->oob_irq_nr);
1141 return ret; 1153 else
1154 sdio_flags = MMC_PM_WAKE_SDIO_IRQ;
1155 if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
1156 brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
1142 } 1157 }
1143 1158
1144 brcmf_sdio_wd_timer(sdiodev->bus, 0); 1159 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1145 1160
1146 return ret; 1161 return 0;
1147} 1162}
1148 1163
1149static int brcmf_ops_sdio_resume(struct device *dev) 1164static int brcmf_ops_sdio_resume(struct device *dev)
@@ -1152,6 +1167,8 @@ static int brcmf_ops_sdio_resume(struct device *dev)
1152 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1167 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1153 1168
1154 brcmf_dbg(SDIO, "Enter\n"); 1169 brcmf_dbg(SDIO, "Enter\n");
1170 if (sdiodev->pdata->oob_irq_supported)
1171 disable_irq_wake(sdiodev->pdata->oob_irq_nr);
1155 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1172 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
1156 atomic_set(&sdiodev->suspend, false); 1173 atomic_set(&sdiodev->suspend, false);
1157 return 0; 1174 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
index a29ac4977b3a..0445163991b7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
@@ -20,13 +20,13 @@
20#include <brcmu_wifi.h> 20#include <brcmu_wifi.h>
21#include <brcmu_utils.h> 21#include <brcmu_utils.h>
22#include <defs.h> 22#include <defs.h>
23#include <dhd.h> 23#include "core.h"
24#include <dhd_dbg.h> 24#include "debug.h"
25#include "fwil.h" 25#include "fwil.h"
26#include "fwil_types.h" 26#include "fwil_types.h"
27#include "btcoex.h" 27#include "btcoex.h"
28#include "p2p.h" 28#include "p2p.h"
29#include "wl_cfg80211.h" 29#include "cfg80211.h"
30 30
31/* T1 start SCO/eSCO priority suppression */ 31/* T1 start SCO/eSCO priority suppression */
32#define BRCMF_BTCOEX_OPPR_WIN_TIME 2000 32#define BRCMF_BTCOEX_OPPR_WIN_TIME 2000
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
index 80e73a1262be..ef344e47218a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
@@ -14,10 +14,10 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef _BRCMF_BUS_H_ 17#ifndef BRCMFMAC_BUS_H
18#define _BRCMF_BUS_H_ 18#define BRCMFMAC_BUS_H
19 19
20#include "dhd_dbg.h" 20#include "debug.h"
21 21
22/* IDs of the 6 default common rings of msgbuf protocol */ 22/* IDs of the 6 default common rings of msgbuf protocol */
23#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0 23#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
@@ -227,8 +227,7 @@ void brcmf_txflowblock(struct device *dev, bool state);
227void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); 227void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
228 228
229int brcmf_bus_start(struct device *dev); 229int brcmf_bus_start(struct device *dev);
230s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, 230s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
231 u32 len);
232void brcmf_bus_add_txhdrlen(struct device *dev, uint len); 231void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
233 232
234#ifdef CONFIG_BRCMFMAC_SDIO 233#ifdef CONFIG_BRCMFMAC_SDIO
@@ -241,4 +240,4 @@ void brcmf_usb_exit(void);
241void brcmf_usb_register(void); 240void brcmf_usb_register(void);
242#endif 241#endif
243 242
244#endif /* _BRCMF_BUS_H_ */ 243#endif /* BRCMFMAC_BUS_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 28fa25b509db..f8a9dfa657ba 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -26,18 +26,18 @@
26#include <brcmu_utils.h> 26#include <brcmu_utils.h>
27#include <defs.h> 27#include <defs.h>
28#include <brcmu_wifi.h> 28#include <brcmu_wifi.h>
29#include "dhd.h" 29#include "core.h"
30#include "dhd_dbg.h" 30#include "debug.h"
31#include "tracepoint.h" 31#include "tracepoint.h"
32#include "fwil_types.h" 32#include "fwil_types.h"
33#include "p2p.h" 33#include "p2p.h"
34#include "btcoex.h" 34#include "btcoex.h"
35#include "wl_cfg80211.h" 35#include "cfg80211.h"
36#include "feature.h" 36#include "feature.h"
37#include "fwil.h" 37#include "fwil.h"
38#include "proto.h" 38#include "proto.h"
39#include "vendor.h" 39#include "vendor.h"
40#include "dhd_bus.h" 40#include "bus.h"
41 41
42#define BRCMF_SCAN_IE_LEN_MAX 2048 42#define BRCMF_SCAN_IE_LEN_MAX 2048
43#define BRCMF_PNO_VERSION 2 43#define BRCMF_PNO_VERSION 2
@@ -299,6 +299,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
299 primary_offset = ch->center_freq1 - ch->chan->center_freq; 299 primary_offset = ch->center_freq1 - ch->chan->center_freq;
300 switch (ch->width) { 300 switch (ch->width) {
301 case NL80211_CHAN_WIDTH_20: 301 case NL80211_CHAN_WIDTH_20:
302 case NL80211_CHAN_WIDTH_20_NOHT:
302 ch_inf.bw = BRCMU_CHAN_BW_20; 303 ch_inf.bw = BRCMU_CHAN_BW_20;
303 WARN_ON(primary_offset != 0); 304 WARN_ON(primary_offset != 0);
304 break; 305 break;
@@ -323,6 +324,10 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
323 ch_inf.sb = BRCMU_CHAN_SB_LU; 324 ch_inf.sb = BRCMU_CHAN_SB_LU;
324 } 325 }
325 break; 326 break;
327 case NL80211_CHAN_WIDTH_80P80:
328 case NL80211_CHAN_WIDTH_160:
329 case NL80211_CHAN_WIDTH_5:
330 case NL80211_CHAN_WIDTH_10:
326 default: 331 default:
327 WARN_ON_ONCE(1); 332 WARN_ON_ONCE(1);
328 } 333 }
@@ -333,6 +338,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
333 case IEEE80211_BAND_5GHZ: 338 case IEEE80211_BAND_5GHZ:
334 ch_inf.band = BRCMU_CHAN_BAND_5G; 339 ch_inf.band = BRCMU_CHAN_BAND_5G;
335 break; 340 break;
341 case IEEE80211_BAND_60GHZ:
336 default: 342 default:
337 WARN_ON_ONCE(1); 343 WARN_ON_ONCE(1);
338 } 344 }
@@ -2779,6 +2785,44 @@ static __always_inline void brcmf_delay(u32 ms)
2779 } 2785 }
2780} 2786}
2781 2787
2788static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
2789 u8 *pattern, u32 patternsize, u8 *mask,
2790 u32 packet_offset)
2791{
2792 struct brcmf_fil_wowl_pattern_le *filter;
2793 u32 masksize;
2794 u32 patternoffset;
2795 u8 *buf;
2796 u32 bufsize;
2797 s32 ret;
2798
2799 masksize = (patternsize + 7) / 8;
2800 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
2801
2802 bufsize = sizeof(*filter) + patternsize + masksize;
2803 buf = kzalloc(bufsize, GFP_KERNEL);
2804 if (!buf)
2805 return -ENOMEM;
2806 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
2807
2808 memcpy(filter->cmd, cmd, 4);
2809 filter->masksize = cpu_to_le32(masksize);
2810 filter->offset = cpu_to_le32(packet_offset);
2811 filter->patternoffset = cpu_to_le32(patternoffset);
2812 filter->patternsize = cpu_to_le32(patternsize);
2813 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
2814
2815 if ((mask) && (masksize))
2816 memcpy(buf + sizeof(*filter), mask, masksize);
2817 if ((pattern) && (patternsize))
2818 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
2819
2820 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
2821
2822 kfree(buf);
2823 return ret;
2824}
2825
2782static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) 2826static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2783{ 2827{
2784 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 2828 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
@@ -2788,10 +2832,11 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2788 brcmf_dbg(TRACE, "Enter\n"); 2832 brcmf_dbg(TRACE, "Enter\n");
2789 2833
2790 if (cfg->wowl_enabled) { 2834 if (cfg->wowl_enabled) {
2835 brcmf_configure_arp_offload(ifp, true);
2791 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, 2836 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
2792 cfg->pre_wowl_pmmode); 2837 cfg->pre_wowl_pmmode);
2793 brcmf_fil_iovar_data_set(ifp, "wowl_pattern", "clr", 4);
2794 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); 2838 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
2839 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
2795 cfg->wowl_enabled = false; 2840 cfg->wowl_enabled = false;
2796 } 2841 }
2797 return 0; 2842 return 0;
@@ -2802,21 +2847,29 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
2802 struct cfg80211_wowlan *wowl) 2847 struct cfg80211_wowlan *wowl)
2803{ 2848{
2804 u32 wowl_config; 2849 u32 wowl_config;
2850 u32 i;
2805 2851
2806 brcmf_dbg(TRACE, "Suspend, wowl config.\n"); 2852 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
2807 2853
2854 brcmf_configure_arp_offload(ifp, false);
2808 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode); 2855 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
2809 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); 2856 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
2810 2857
2811 wowl_config = 0; 2858 wowl_config = 0;
2812 if (wowl->disconnect) 2859 if (wowl->disconnect)
2813 wowl_config |= WL_WOWL_DIS | WL_WOWL_BCN | WL_WOWL_RETR; 2860 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
2814 /* Note: if "wowl" target and not "wowlpf" then wowl_bcn_loss
2815 * should be configured. This paramater is not supported by
2816 * wowlpf.
2817 */
2818 if (wowl->magic_pkt) 2861 if (wowl->magic_pkt)
2819 wowl_config |= WL_WOWL_MAGIC; 2862 wowl_config |= BRCMF_WOWL_MAGIC;
2863 if ((wowl->patterns) && (wowl->n_patterns)) {
2864 wowl_config |= BRCMF_WOWL_NET;
2865 for (i = 0; i < wowl->n_patterns; i++) {
2866 brcmf_config_wowl_pattern(ifp, "add",
2867 (u8 *)wowl->patterns[i].pattern,
2868 wowl->patterns[i].pattern_len,
2869 (u8 *)wowl->patterns[i].mask,
2870 wowl->patterns[i].pkt_offset);
2871 }
2872 }
2820 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); 2873 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
2821 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); 2874 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
2822 brcmf_bus_wowl_config(cfg->pub->bus_if, true); 2875 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
@@ -3998,24 +4051,24 @@ brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3998 4051
3999static int 4052static int
4000brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, 4053brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4001 const u8 *mac) 4054 struct station_del_parameters *params)
4002{ 4055{
4003 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 4056 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4004 struct brcmf_scb_val_le scbval; 4057 struct brcmf_scb_val_le scbval;
4005 struct brcmf_if *ifp = netdev_priv(ndev); 4058 struct brcmf_if *ifp = netdev_priv(ndev);
4006 s32 err; 4059 s32 err;
4007 4060
4008 if (!mac) 4061 if (!params->mac)
4009 return -EFAULT; 4062 return -EFAULT;
4010 4063
4011 brcmf_dbg(TRACE, "Enter %pM\n", mac); 4064 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4012 4065
4013 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) 4066 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4014 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; 4067 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4015 if (!check_vif_up(ifp->vif)) 4068 if (!check_vif_up(ifp->vif))
4016 return -EIO; 4069 return -EIO;
4017 4070
4018 memcpy(&scbval.ea, mac, ETH_ALEN); 4071 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4019 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); 4072 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4020 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, 4073 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4021 &scbval, sizeof(scbval)); 4074 &scbval, sizeof(scbval));
@@ -5440,10 +5493,13 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5440 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 5493 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5441} 5494}
5442 5495
5443
5444#ifdef CONFIG_PM 5496#ifdef CONFIG_PM
5445static const struct wiphy_wowlan_support brcmf_wowlan_support = { 5497static const struct wiphy_wowlan_support brcmf_wowlan_support = {
5446 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, 5498 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
5499 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
5500 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
5501 .pattern_min_len = 1,
5502 .max_pkt_offset = 1500,
5447}; 5503};
5448#endif 5504#endif
5449 5505
@@ -5607,7 +5663,8 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5607 return wdev->iftype; 5663 return wdev->iftype;
5608} 5664}
5609 5665
5610bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state) 5666bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
5667 unsigned long state)
5611{ 5668{
5612 struct brcmf_cfg80211_vif *vif; 5669 struct brcmf_cfg80211_vif *vif;
5613 5670
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
index 6abf94e41d3d..2a5b22cb3fef 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
@@ -14,8 +14,8 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef _wl_cfg80211_h_ 17#ifndef BRCMFMAC_CFG80211_H
18#define _wl_cfg80211_h_ 18#define BRCMFMAC_CFG80211_H
19 19
20/* for brcmu_d11inf */ 20/* for brcmu_d11inf */
21#include <brcmu_d11.h> 21#include <brcmu_d11.h>
@@ -480,7 +480,8 @@ const struct brcmf_tlv *
480brcmf_parse_tlvs(const void *buf, int buflen, uint key); 480brcmf_parse_tlvs(const void *buf, int buflen, uint key);
481u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, 481u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
482 struct ieee80211_channel *ch); 482 struct ieee80211_channel *ch);
483bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state); 483bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
484 unsigned long state);
484void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, 485void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
485 struct brcmf_cfg80211_vif *vif); 486 struct brcmf_cfg80211_vif *vif);
486bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg); 487bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
@@ -493,4 +494,4 @@ void brcmf_set_mpc(struct brcmf_if *ndev, int mpc);
493void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); 494void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
494void brcmf_cfg80211_free_netdev(struct net_device *ndev); 495void brcmf_cfg80211_free_netdev(struct net_device *ndev);
495 496
496#endif /* _wl_cfg80211_h_ */ 497#endif /* BRCMFMAC_CFG80211_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index 95efde868db8..ddae0b5e56ec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -25,7 +25,7 @@
25#include <brcm_hw_ids.h> 25#include <brcm_hw_ids.h>
26#include <brcmu_utils.h> 26#include <brcmu_utils.h>
27#include <chipcommon.h> 27#include <chipcommon.h>
28#include "dhd_dbg.h" 28#include "debug.h"
29#include "chip.h" 29#include "chip.h"
30 30
31/* SOC Interconnect types (aka chip types) */ 31/* SOC Interconnect types (aka chip types) */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/common.c b/drivers/net/wireless/brcm80211/brcmfmac/common.c
new file mode 100644
index 000000000000..1861a13e8d03
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/common.c
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/netdevice.h>
20#include <brcmu_wifi.h>
21#include <brcmu_utils.h>
22#include "core.h"
23#include "bus.h"
24#include "debug.h"
25#include "fwil.h"
26#include "fwil_types.h"
27#include "tracepoint.h"
28
29#define BRCMF_DEFAULT_BCN_TIMEOUT 3
30#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
31#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
32
33/* boost value for RSSI_DELTA in preferred join selection */
34#define BRCMF_JOIN_PREF_RSSI_BOOST 8
35
36int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
37{
38 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
39 u8 buf[BRCMF_DCMD_SMLEN];
40 struct brcmf_join_pref_params join_pref_params[2];
41 char *ptr;
42 s32 err;
43
44 /* retreive mac address */
45 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
46 sizeof(ifp->mac_addr));
47 if (err < 0) {
48 brcmf_err("Retreiving cur_etheraddr failed, %d\n",
49 err);
50 goto done;
51 }
52 memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
53
54 /* query for 'ver' to get version info from firmware */
55 memset(buf, 0, sizeof(buf));
56 strcpy(buf, "ver");
57 err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
58 if (err < 0) {
59 brcmf_err("Retreiving version information failed, %d\n",
60 err);
61 goto done;
62 }
63 ptr = (char *)buf;
64 strsep(&ptr, "\n");
65
66 /* Print fw version info */
67 brcmf_err("Firmware version = %s\n", buf);
68
69 /* locate firmware version number for ethtool */
70 ptr = strrchr(buf, ' ') + 1;
71 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
72
73 /* set mpc */
74 err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
75 if (err) {
76 brcmf_err("failed setting mpc\n");
77 goto done;
78 }
79
80 /*
81 * Setup timeout if Beacons are lost and roam is off to report
82 * link down
83 */
84 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout",
85 BRCMF_DEFAULT_BCN_TIMEOUT);
86 if (err) {
87 brcmf_err("bcn_timeout error (%d)\n", err);
88 goto done;
89 }
90
91 /* Enable/Disable build-in roaming to allowed ext supplicant to take
92 * of romaing
93 */
94 err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
95 if (err) {
96 brcmf_err("roam_off error (%d)\n", err);
97 goto done;
98 }
99
100 /* Setup join_pref to select target by RSSI(with boost on 5GHz) */
101 join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
102 join_pref_params[0].len = 2;
103 join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
104 join_pref_params[0].band = WLC_BAND_5G;
105 join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
106 join_pref_params[1].len = 2;
107 join_pref_params[1].rssi_gain = 0;
108 join_pref_params[1].band = 0;
109 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
110 sizeof(join_pref_params));
111 if (err)
112 brcmf_err("Set join_pref error (%d)\n", err);
113
114 /* Setup event_msgs, enable E_IF */
115 err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
116 BRCMF_EVENTING_MASK_LEN);
117 if (err) {
118 brcmf_err("Get event_msgs error (%d)\n", err);
119 goto done;
120 }
121 setbit(eventmask, BRCMF_E_IF);
122 err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
123 BRCMF_EVENTING_MASK_LEN);
124 if (err) {
125 brcmf_err("Set event_msgs error (%d)\n", err);
126 goto done;
127 }
128
129 /* Setup default scan channel time */
130 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
131 BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
132 if (err) {
133 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
134 err);
135 goto done;
136 }
137
138 /* Setup default scan unassoc time */
139 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
140 BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
141 if (err) {
142 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
143 err);
144 goto done;
145 }
146
147 /* do bus specific preinit here */
148 err = brcmf_bus_preinit(ifp->drvr->bus_if);
149done:
150 return err;
151}
152
153#if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
154void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
155{
156 struct va_format vaf = {
157 .fmt = fmt,
158 };
159 va_list args;
160
161 va_start(args, fmt);
162 vaf.va = &args;
163 if (brcmf_msg_level & level)
164 pr_debug("%s %pV", func, &vaf);
165 trace_brcmf_dbg(level, func, &vaf);
166 va_end(args);
167}
168#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
index c6d65b8e1e15..77656c711bed 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
@@ -19,7 +19,7 @@
19#include <brcmu_utils.h> 19#include <brcmu_utils.h>
20#include <brcmu_wifi.h> 20#include <brcmu_wifi.h>
21 21
22#include "dhd.h" 22#include "core.h"
23#include "commonring.h" 23#include "commonring.h"
24 24
25 25
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index fb1043908a23..f407665cb1ea 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -22,12 +22,12 @@
22#include <brcmu_utils.h> 22#include <brcmu_utils.h>
23#include <brcmu_wifi.h> 23#include <brcmu_wifi.h>
24 24
25#include "dhd.h" 25#include "core.h"
26#include "dhd_bus.h" 26#include "bus.h"
27#include "dhd_dbg.h" 27#include "debug.h"
28#include "fwil_types.h" 28#include "fwil_types.h"
29#include "p2p.h" 29#include "p2p.h"
30#include "wl_cfg80211.h" 30#include "cfg80211.h"
31#include "fwil.h" 31#include "fwil.h"
32#include "fwsignal.h" 32#include "fwsignal.h"
33#include "feature.h" 33#include "feature.h"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/core.h
index 5e4317dbc2b0..98228e922d3a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -18,8 +18,8 @@
18 * Common types * 18 * Common types *
19 */ 19 */
20 20
21#ifndef _BRCMF_H_ 21#ifndef BRCMFMAC_CORE_H
22#define _BRCMF_H_ 22#define BRCMFMAC_CORE_H
23 23
24#include "fweh.h" 24#include "fweh.h"
25 25
@@ -83,7 +83,6 @@ struct brcmf_pub {
83 /* Internal brcmf items */ 83 /* Internal brcmf items */
84 uint hdrlen; /* Total BRCMF header length (proto + bus) */ 84 uint hdrlen; /* Total BRCMF header length (proto + bus) */
85 uint rxsz; /* Rx buffer size bus module should use */ 85 uint rxsz; /* Rx buffer size bus module should use */
86 u8 wme_dp; /* wme discard priority */
87 86
88 /* Dongle media info */ 87 /* Dongle media info */
89 char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN]; 88 char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
@@ -186,4 +185,4 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
186/* Sets dongle media info (drv_version, mac address). */ 185/* Sets dongle media info (drv_version, mac address). */
187int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); 186int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
188 187
189#endif /* _BRCMF_H_ */ 188#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
index be9f4f829192..9b473d50b005 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
@@ -19,9 +19,9 @@
19 19
20#include <brcmu_wifi.h> 20#include <brcmu_wifi.h>
21#include <brcmu_utils.h> 21#include <brcmu_utils.h>
22#include "dhd.h" 22#include "core.h"
23#include "dhd_bus.h" 23#include "bus.h"
24#include "dhd_dbg.h" 24#include "debug.h"
25 25
26static struct dentry *root_folder; 26static struct dentry *root_folder;
27 27
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
index dec40d316c82..eb0b8c47479d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
@@ -14,8 +14,8 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef _BRCMF_DBG_H_ 17#ifndef BRCMFMAC_DEBUG_H
18#define _BRCMF_DBG_H_ 18#define BRCMFMAC_DEBUG_H
19 19
20/* message levels */ 20/* message levels */
21#define BRCMF_TRACE_VAL 0x00000002 21#define BRCMF_TRACE_VAL 0x00000002
@@ -133,4 +133,4 @@ int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
133} 133}
134#endif 134#endif
135 135
136#endif /* _BRCMF_DBG_H_ */ 136#endif /* BRCMFMAC_DEBUG_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
deleted file mode 100644
index d991f8e3d9ec..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ /dev/null
@@ -1,400 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/netdevice.h>
20#include <brcmu_wifi.h>
21#include <brcmu_utils.h>
22#include "dhd.h"
23#include "dhd_bus.h"
24#include "dhd_dbg.h"
25#include "fwil.h"
26#include "fwil_types.h"
27#include "tracepoint.h"
28
29#define PKTFILTER_BUF_SIZE 128
30#define BRCMF_DEFAULT_BCN_TIMEOUT 3
31#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
32#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
33#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
34
35/* boost value for RSSI_DELTA in preferred join selection */
36#define BRCMF_JOIN_PREF_RSSI_BOOST 8
37
38
39bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
40 struct sk_buff *pkt, int prec)
41{
42 struct sk_buff *p;
43 int eprec = -1; /* precedence to evict from */
44 bool discard_oldest;
45 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
46 struct brcmf_pub *drvr = bus_if->drvr;
47
48 /* Fast case, precedence queue is not full and we are also not
49 * exceeding total queue length
50 */
51 if (!pktq_pfull(q, prec) && !pktq_full(q)) {
52 brcmu_pktq_penq(q, prec, pkt);
53 return true;
54 }
55
56 /* Determine precedence from which to evict packet, if any */
57 if (pktq_pfull(q, prec))
58 eprec = prec;
59 else if (pktq_full(q)) {
60 p = brcmu_pktq_peek_tail(q, &eprec);
61 if (eprec > prec)
62 return false;
63 }
64
65 /* Evict if needed */
66 if (eprec >= 0) {
67 /* Detect queueing to unconfigured precedence */
68 discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
69 if (eprec == prec && !discard_oldest)
70 return false; /* refuse newer (incoming) packet */
71 /* Evict packet according to discard policy */
72 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
73 brcmu_pktq_pdeq_tail(q, eprec);
74 if (p == NULL)
75 brcmf_err("brcmu_pktq_penq() failed, oldest %d\n",
76 discard_oldest);
77
78 brcmu_pkt_buf_free_skb(p);
79 }
80
81 /* Enqueue */
82 p = brcmu_pktq_penq(q, prec, pkt);
83 if (p == NULL)
84 brcmf_err("brcmu_pktq_penq() failed\n");
85
86 return p != NULL;
87}
88
89/* Convert user's input in hex pattern to byte-size mask */
90static int brcmf_c_pattern_atoh(char *src, char *dst)
91{
92 int i;
93 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
94 brcmf_err("Mask invalid format. Needs to start with 0x\n");
95 return -EINVAL;
96 }
97 src = src + 2; /* Skip past 0x */
98 if (strlen(src) % 2 != 0) {
99 brcmf_err("Mask invalid format. Length must be even.\n");
100 return -EINVAL;
101 }
102 for (i = 0; *src != '\0'; i++) {
103 unsigned long res;
104 char num[3];
105 strncpy(num, src, 2);
106 num[2] = '\0';
107 if (kstrtoul(num, 16, &res))
108 return -EINVAL;
109 dst[i] = (u8)res;
110 src += 2;
111 }
112 return i;
113}
114
115static void
116brcmf_c_pktfilter_offload_enable(struct brcmf_if *ifp, char *arg, int enable,
117 int master_mode)
118{
119 unsigned long res;
120 char *argv;
121 char *arg_save = NULL, *arg_org = NULL;
122 s32 err;
123 struct brcmf_pkt_filter_enable_le enable_parm;
124
125 arg_save = kstrdup(arg, GFP_ATOMIC);
126 if (!arg_save)
127 goto fail;
128
129 arg_org = arg_save;
130
131 argv = strsep(&arg_save, " ");
132
133 if (argv == NULL) {
134 brcmf_err("No args provided\n");
135 goto fail;
136 }
137
138 /* Parse packet filter id. */
139 enable_parm.id = 0;
140 if (!kstrtoul(argv, 0, &res))
141 enable_parm.id = cpu_to_le32((u32)res);
142
143 /* Enable/disable the specified filter. */
144 enable_parm.enable = cpu_to_le32(enable);
145
146 err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable", &enable_parm,
147 sizeof(enable_parm));
148 if (err)
149 brcmf_err("Set pkt_filter_enable error (%d)\n", err);
150
151 /* Control the master mode */
152 err = brcmf_fil_iovar_int_set(ifp, "pkt_filter_mode", master_mode);
153 if (err)
154 brcmf_err("Set pkt_filter_mode error (%d)\n", err);
155
156fail:
157 kfree(arg_org);
158}
159
160static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg)
161{
162 struct brcmf_pkt_filter_le *pkt_filter;
163 unsigned long res;
164 int buf_len;
165 s32 err;
166 u32 mask_size;
167 u32 pattern_size;
168 char *argv[8], *buf = NULL;
169 int i = 0;
170 char *arg_save = NULL, *arg_org = NULL;
171
172 arg_save = kstrdup(arg, GFP_ATOMIC);
173 if (!arg_save)
174 goto fail;
175
176 arg_org = arg_save;
177
178 buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
179 if (!buf)
180 goto fail;
181
182 argv[i] = strsep(&arg_save, " ");
183 while (argv[i]) {
184 i++;
185 if (i >= 8) {
186 brcmf_err("Too many parameters\n");
187 goto fail;
188 }
189 argv[i] = strsep(&arg_save, " ");
190 }
191
192 if (i != 6) {
193 brcmf_err("Not enough args provided %d\n", i);
194 goto fail;
195 }
196
197 pkt_filter = (struct brcmf_pkt_filter_le *)buf;
198
199 /* Parse packet filter id. */
200 pkt_filter->id = 0;
201 if (!kstrtoul(argv[0], 0, &res))
202 pkt_filter->id = cpu_to_le32((u32)res);
203
204 /* Parse filter polarity. */
205 pkt_filter->negate_match = 0;
206 if (!kstrtoul(argv[1], 0, &res))
207 pkt_filter->negate_match = cpu_to_le32((u32)res);
208
209 /* Parse filter type. */
210 pkt_filter->type = 0;
211 if (!kstrtoul(argv[2], 0, &res))
212 pkt_filter->type = cpu_to_le32((u32)res);
213
214 /* Parse pattern filter offset. */
215 pkt_filter->u.pattern.offset = 0;
216 if (!kstrtoul(argv[3], 0, &res))
217 pkt_filter->u.pattern.offset = cpu_to_le32((u32)res);
218
219 /* Parse pattern filter mask. */
220 mask_size = brcmf_c_pattern_atoh(argv[4],
221 (char *)pkt_filter->u.pattern.mask_and_pattern);
222
223 /* Parse pattern filter pattern. */
224 pattern_size = brcmf_c_pattern_atoh(argv[5],
225 (char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]);
226
227 if (mask_size != pattern_size) {
228 brcmf_err("Mask and pattern not the same size\n");
229 goto fail;
230 }
231
232 pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size);
233 buf_len = offsetof(struct brcmf_pkt_filter_le,
234 u.pattern.mask_and_pattern);
235 buf_len += mask_size + pattern_size;
236
237 err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter,
238 buf_len);
239 if (err)
240 brcmf_err("Set pkt_filter_add error (%d)\n", err);
241
242fail:
243 kfree(arg_org);
244
245 kfree(buf);
246}
247
248int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
249{
250 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
251 u8 buf[BRCMF_DCMD_SMLEN];
252 struct brcmf_join_pref_params join_pref_params[2];
253 char *ptr;
254 s32 err;
255
256 /* retreive mac address */
257 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
258 sizeof(ifp->mac_addr));
259 if (err < 0) {
260 brcmf_err("Retreiving cur_etheraddr failed, %d\n",
261 err);
262 goto done;
263 }
264 memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
265
266 /* query for 'ver' to get version info from firmware */
267 memset(buf, 0, sizeof(buf));
268 strcpy(buf, "ver");
269 err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
270 if (err < 0) {
271 brcmf_err("Retreiving version information failed, %d\n",
272 err);
273 goto done;
274 }
275 ptr = (char *)buf;
276 strsep(&ptr, "\n");
277
278 /* Print fw version info */
279 brcmf_err("Firmware version = %s\n", buf);
280
281 /* locate firmware version number for ethtool */
282 ptr = strrchr(buf, ' ') + 1;
283 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
284
285 /* set mpc */
286 err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
287 if (err) {
288 brcmf_err("failed setting mpc\n");
289 goto done;
290 }
291
292 /*
293 * Setup timeout if Beacons are lost and roam is off to report
294 * link down
295 */
296 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout",
297 BRCMF_DEFAULT_BCN_TIMEOUT);
298 if (err) {
299 brcmf_err("bcn_timeout error (%d)\n", err);
300 goto done;
301 }
302
303 /* Enable/Disable build-in roaming to allowed ext supplicant to take
304 * of romaing
305 */
306 err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
307 if (err) {
308 brcmf_err("roam_off error (%d)\n", err);
309 goto done;
310 }
311
312 /* Setup join_pref to select target by RSSI(with boost on 5GHz) */
313 join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
314 join_pref_params[0].len = 2;
315 join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
316 join_pref_params[0].band = WLC_BAND_5G;
317 join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
318 join_pref_params[1].len = 2;
319 join_pref_params[1].rssi_gain = 0;
320 join_pref_params[1].band = 0;
321 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
322 sizeof(join_pref_params));
323 if (err)
324 brcmf_err("Set join_pref error (%d)\n", err);
325
326 /* Setup event_msgs, enable E_IF */
327 err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
328 BRCMF_EVENTING_MASK_LEN);
329 if (err) {
330 brcmf_err("Get event_msgs error (%d)\n", err);
331 goto done;
332 }
333 setbit(eventmask, BRCMF_E_IF);
334 err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
335 BRCMF_EVENTING_MASK_LEN);
336 if (err) {
337 brcmf_err("Set event_msgs error (%d)\n", err);
338 goto done;
339 }
340
341 /* Setup default scan channel time */
342 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
343 BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
344 if (err) {
345 brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
346 err);
347 goto done;
348 }
349
350 /* Setup default scan unassoc time */
351 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
352 BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
353 if (err) {
354 brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
355 err);
356 goto done;
357 }
358
359 /* Setup packet filter */
360 brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
361 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
362 0, true);
363
364 /* do bus specific preinit here */
365 err = brcmf_bus_preinit(ifp->drvr->bus_if);
366done:
367 return err;
368}
369
370#ifdef CONFIG_BRCM_TRACING
371void __brcmf_err(const char *func, const char *fmt, ...)
372{
373 struct va_format vaf = {
374 .fmt = fmt,
375 };
376 va_list args;
377
378 va_start(args, fmt);
379 vaf.va = &args;
380 pr_err("%s: %pV", func, &vaf);
381 trace_brcmf_err(func, &vaf);
382 va_end(args);
383}
384#endif
385#if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
386void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
387{
388 struct va_format vaf = {
389 .fmt = fmt,
390 };
391 va_list args;
392
393 va_start(args, fmt);
394 vaf.va = &args;
395 if (brcmf_msg_level & level)
396 pr_debug("%s %pV", func, &vaf);
397 trace_brcmf_dbg(level, func, &vaf);
398 va_end(args);
399}
400#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
index aed53acef456..931f68aefaa4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
@@ -17,18 +17,13 @@
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18 18
19#include <brcm_hw_ids.h> 19#include <brcm_hw_ids.h>
20#include "dhd.h" 20#include "core.h"
21#include "dhd_bus.h" 21#include "bus.h"
22#include "dhd_dbg.h" 22#include "debug.h"
23#include "fwil.h" 23#include "fwil.h"
24#include "feature.h" 24#include "feature.h"
25 25
26/* 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. 27 * expand feature list to array of feature strings.
33 */ 28 */
34#define BRCMF_FEAT_DEF(_f) \ 29#define BRCMF_FEAT_DEF(_f) \
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 8ea9f283d2b8..1ff787d1a36b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -20,7 +20,7 @@
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include <linux/module.h> 21#include <linux/module.h>
22 22
23#include "dhd_dbg.h" 23#include "debug.h"
24#include "firmware.h" 24#include "firmware.h"
25 25
26char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; 26char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
@@ -262,8 +262,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
262 262
263fail: 263fail:
264 brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); 264 brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
265 if (fwctx->code) 265 release_firmware(fwctx->code);
266 release_firmware(fwctx->code);
267 device_release_driver(fwctx->dev); 266 device_release_driver(fwctx->dev);
268 kfree(fwctx); 267 kfree(fwctx);
269} 268}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
index 1faa929f5fff..44f3a84d1999 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
@@ -19,9 +19,9 @@
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <brcmu_utils.h> 20#include <brcmu_utils.h>
21 21
22#include "dhd.h" 22#include "core.h"
23#include "dhd_dbg.h" 23#include "debug.h"
24#include "dhd_bus.h" 24#include "bus.h"
25#include "proto.h" 25#include "proto.h"
26#include "flowring.h" 26#include "flowring.h"
27#include "msgbuf.h" 27#include "msgbuf.h"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index 44fc85f68f7a..7338b335e153 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -18,8 +18,8 @@
18#include "brcmu_wifi.h" 18#include "brcmu_wifi.h"
19#include "brcmu_utils.h" 19#include "brcmu_utils.h"
20 20
21#include "dhd.h" 21#include "core.h"
22#include "dhd_dbg.h" 22#include "debug.h"
23#include "tracepoint.h" 23#include "tracepoint.h"
24#include "fwsignal.h" 24#include "fwsignal.h"
25#include "fweh.h" 25#include "fweh.h"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index ded328f80cd1..51f88c11e642 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -22,9 +22,9 @@
22#include <linux/netdevice.h> 22#include <linux/netdevice.h>
23#include <brcmu_utils.h> 23#include <brcmu_utils.h>
24#include <brcmu_wifi.h> 24#include <brcmu_wifi.h>
25#include "dhd.h" 25#include "core.h"
26#include "dhd_bus.h" 26#include "bus.h"
27#include "dhd_dbg.h" 27#include "debug.h"
28#include "tracepoint.h" 28#include "tracepoint.h"
29#include "fwil.h" 29#include "fwil.h"
30#include "proto.h" 30#include "proto.h"
@@ -32,6 +32,76 @@
32 32
33#define MAX_HEX_DUMP_LEN 64 33#define MAX_HEX_DUMP_LEN 64
34 34
35#ifdef DEBUG
36static const char * const brcmf_fil_errstr[] = {
37 "BCME_OK",
38 "BCME_ERROR",
39 "BCME_BADARG",
40 "BCME_BADOPTION",
41 "BCME_NOTUP",
42 "BCME_NOTDOWN",
43 "BCME_NOTAP",
44 "BCME_NOTSTA",
45 "BCME_BADKEYIDX",
46 "BCME_RADIOOFF",
47 "BCME_NOTBANDLOCKED",
48 "BCME_NOCLK",
49 "BCME_BADRATESET",
50 "BCME_BADBAND",
51 "BCME_BUFTOOSHORT",
52 "BCME_BUFTOOLONG",
53 "BCME_BUSY",
54 "BCME_NOTASSOCIATED",
55 "BCME_BADSSIDLEN",
56 "BCME_OUTOFRANGECHAN",
57 "BCME_BADCHAN",
58 "BCME_BADADDR",
59 "BCME_NORESOURCE",
60 "BCME_UNSUPPORTED",
61 "BCME_BADLEN",
62 "BCME_NOTREADY",
63 "BCME_EPERM",
64 "BCME_NOMEM",
65 "BCME_ASSOCIATED",
66 "BCME_RANGE",
67 "BCME_NOTFOUND",
68 "BCME_WME_NOT_ENABLED",
69 "BCME_TSPEC_NOTFOUND",
70 "BCME_ACM_NOTSUPPORTED",
71 "BCME_NOT_WME_ASSOCIATION",
72 "BCME_SDIO_ERROR",
73 "BCME_DONGLE_DOWN",
74 "BCME_VERSION",
75 "BCME_TXFAIL",
76 "BCME_RXFAIL",
77 "BCME_NODEVICE",
78 "BCME_NMODE_DISABLED",
79 "BCME_NONRESIDENT",
80 "BCME_SCANREJECT",
81 "BCME_USAGE_ERROR",
82 "BCME_IOCTL_ERROR",
83 "BCME_SERIAL_PORT_ERR",
84 "BCME_DISABLED",
85 "BCME_DECERR",
86 "BCME_ENCERR",
87 "BCME_MICERR",
88 "BCME_REPLAY",
89 "BCME_IE_NOTFOUND",
90};
91
92static const char *brcmf_fil_get_errstr(u32 err)
93{
94 if (err >= ARRAY_SIZE(brcmf_fil_errstr))
95 return "(unknown)";
96
97 return brcmf_fil_errstr[err];
98}
99#else
100static const char *brcmf_fil_get_errstr(u32 err)
101{
102 return "";
103}
104#endif /* DEBUG */
35 105
36static s32 106static s32
37brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) 107brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
@@ -52,11 +122,11 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
52 err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); 122 err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
53 123
54 if (err >= 0) 124 if (err >= 0)
55 err = 0; 125 return 0;
56 else
57 brcmf_dbg(FIL, "Failed err=%d\n", err);
58 126
59 return err; 127 brcmf_dbg(FIL, "Failed: %s (%d)\n",
128 brcmf_fil_get_errstr((u32)(-err)), err);
129 return -EBADE;
60} 130}
61 131
62s32 132s32
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 5ff5cd0bb032..ba64b292f7a5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -55,59 +55,63 @@
55 55
56/* WOWL bits */ 56/* WOWL bits */
57/* Wakeup on Magic packet: */ 57/* Wakeup on Magic packet: */
58#define WL_WOWL_MAGIC (1 << 0) 58#define BRCMF_WOWL_MAGIC (1 << 0)
59/* Wakeup on Netpattern */ 59/* Wakeup on Netpattern */
60#define WL_WOWL_NET (1 << 1) 60#define BRCMF_WOWL_NET (1 << 1)
61/* Wakeup on loss-of-link due to Disassoc/Deauth: */ 61/* Wakeup on loss-of-link due to Disassoc/Deauth: */
62#define WL_WOWL_DIS (1 << 2) 62#define BRCMF_WOWL_DIS (1 << 2)
63/* Wakeup on retrograde TSF: */ 63/* Wakeup on retrograde TSF: */
64#define WL_WOWL_RETR (1 << 3) 64#define BRCMF_WOWL_RETR (1 << 3)
65/* Wakeup on loss of beacon: */ 65/* Wakeup on loss of beacon: */
66#define WL_WOWL_BCN (1 << 4) 66#define BRCMF_WOWL_BCN (1 << 4)
67/* Wakeup after test: */ 67/* Wakeup after test: */
68#define WL_WOWL_TST (1 << 5) 68#define BRCMF_WOWL_TST (1 << 5)
69/* Wakeup after PTK refresh: */ 69/* Wakeup after PTK refresh: */
70#define WL_WOWL_M1 (1 << 6) 70#define BRCMF_WOWL_M1 (1 << 6)
71/* Wakeup after receipt of EAP-Identity Req: */ 71/* Wakeup after receipt of EAP-Identity Req: */
72#define WL_WOWL_EAPID (1 << 7) 72#define BRCMF_WOWL_EAPID (1 << 7)
73/* Wakeind via PME(0) or GPIO(1): */ 73/* Wakeind via PME(0) or GPIO(1): */
74#define WL_WOWL_PME_GPIO (1 << 8) 74#define BRCMF_WOWL_PME_GPIO (1 << 8)
75/* need tkip phase 1 key to be updated by the driver: */ 75/* need tkip phase 1 key to be updated by the driver: */
76#define WL_WOWL_NEEDTKIP1 (1 << 9) 76#define BRCMF_WOWL_NEEDTKIP1 (1 << 9)
77/* enable wakeup if GTK fails: */ 77/* enable wakeup if GTK fails: */
78#define WL_WOWL_GTK_FAILURE (1 << 10) 78#define BRCMF_WOWL_GTK_FAILURE (1 << 10)
79/* support extended magic packets: */ 79/* support extended magic packets: */
80#define WL_WOWL_EXTMAGPAT (1 << 11) 80#define BRCMF_WOWL_EXTMAGPAT (1 << 11)
81/* support ARP/NS/keepalive offloading: */ 81/* support ARP/NS/keepalive offloading: */
82#define WL_WOWL_ARPOFFLOAD (1 << 12) 82#define BRCMF_WOWL_ARPOFFLOAD (1 << 12)
83/* read protocol version for EAPOL frames: */ 83/* read protocol version for EAPOL frames: */
84#define WL_WOWL_WPA2 (1 << 13) 84#define BRCMF_WOWL_WPA2 (1 << 13)
85/* If the bit is set, use key rotaton: */ 85/* If the bit is set, use key rotaton: */
86#define WL_WOWL_KEYROT (1 << 14) 86#define BRCMF_WOWL_KEYROT (1 << 14)
87/* If the bit is set, frm received was bcast frame: */ 87/* If the bit is set, frm received was bcast frame: */
88#define WL_WOWL_BCAST (1 << 15) 88#define BRCMF_WOWL_BCAST (1 << 15)
89/* If the bit is set, scan offload is enabled: */ 89/* If the bit is set, scan offload is enabled: */
90#define WL_WOWL_SCANOL (1 << 16) 90#define BRCMF_WOWL_SCANOL (1 << 16)
91/* Wakeup on tcpkeep alive timeout: */ 91/* Wakeup on tcpkeep alive timeout: */
92#define WL_WOWL_TCPKEEP_TIME (1 << 17) 92#define BRCMF_WOWL_TCPKEEP_TIME (1 << 17)
93/* Wakeup on mDNS Conflict Resolution: */ 93/* Wakeup on mDNS Conflict Resolution: */
94#define WL_WOWL_MDNS_CONFLICT (1 << 18) 94#define BRCMF_WOWL_MDNS_CONFLICT (1 << 18)
95/* Wakeup on mDNS Service Connect: */ 95/* Wakeup on mDNS Service Connect: */
96#define WL_WOWL_MDNS_SERVICE (1 << 19) 96#define BRCMF_WOWL_MDNS_SERVICE (1 << 19)
97/* tcp keepalive got data: */ 97/* tcp keepalive got data: */
98#define WL_WOWL_TCPKEEP_DATA (1 << 20) 98#define BRCMF_WOWL_TCPKEEP_DATA (1 << 20)
99/* Firmware died in wowl mode: */ 99/* Firmware died in wowl mode: */
100#define WL_WOWL_FW_HALT (1 << 21) 100#define BRCMF_WOWL_FW_HALT (1 << 21)
101/* Enable detection of radio button changes: */ 101/* Enable detection of radio button changes: */
102#define WL_WOWL_ENAB_HWRADIO (1 << 22) 102#define BRCMF_WOWL_ENAB_HWRADIO (1 << 22)
103/* Offloads detected MIC failure(s): */ 103/* Offloads detected MIC failure(s): */
104#define WL_WOWL_MIC_FAIL (1 << 23) 104#define BRCMF_WOWL_MIC_FAIL (1 << 23)
105/* Wakeup in Unassociated state (Net/Magic Pattern): */ 105/* Wakeup in Unassociated state (Net/Magic Pattern): */
106#define WL_WOWL_UNASSOC (1 << 24) 106#define BRCMF_WOWL_UNASSOC (1 << 24)
107/* Wakeup if received matched secured pattern: */ 107/* Wakeup if received matched secured pattern: */
108#define WL_WOWL_SECURE (1 << 25) 108#define BRCMF_WOWL_SECURE (1 << 25)
109/* Link Down indication in WoWL mode: */ 109/* Link Down indication in WoWL mode: */
110#define WL_WOWL_LINKDOWN (1 << 31) 110#define BRCMF_WOWL_LINKDOWN (1 << 31)
111
112#define BRCMF_WOWL_MAXPATTERNS 8
113#define BRCMF_WOWL_MAXPATTERNSIZE 128
114
111 115
112/* join preference types for join_pref iovar */ 116/* join preference types for join_pref iovar */
113enum brcmf_join_pref_types { 117enum brcmf_join_pref_types {
@@ -124,6 +128,12 @@ enum brcmf_fil_p2p_if_types {
124 BRCMF_FIL_P2P_IF_DEV, 128 BRCMF_FIL_P2P_IF_DEV,
125}; 129};
126 130
131enum brcmf_wowl_pattern_type {
132 BRCMF_WOWL_PATTERN_TYPE_BITMAP = 0,
133 BRCMF_WOWL_PATTERN_TYPE_ARP,
134 BRCMF_WOWL_PATTERN_TYPE_NA
135};
136
127struct brcmf_fil_p2p_if_le { 137struct brcmf_fil_p2p_if_le {
128 u8 addr[ETH_ALEN]; 138 u8 addr[ETH_ALEN];
129 __le16 type; 139 __le16 type;
@@ -484,4 +494,29 @@ struct brcmf_rx_mgmt_data {
484 __be32 rate; 494 __be32 rate;
485}; 495};
486 496
497/**
498 * struct brcmf_fil_wowl_pattern_le - wowl pattern configuration struct.
499 *
500 * @cmd: "add", "del" or "clr".
501 * @masksize: Size of the mask in #of bytes
502 * @offset: Pattern byte offset in packet
503 * @patternoffset: Offset of start of pattern. Starting from field masksize.
504 * @patternsize: Size of the pattern itself in #of bytes
505 * @id: id
506 * @reasonsize: Size of the wakeup reason code
507 * @type: Type of pattern (enum brcmf_wowl_pattern_type)
508 */
509struct brcmf_fil_wowl_pattern_le {
510 u8 cmd[4];
511 __le32 masksize;
512 __le32 offset;
513 __le32 patternoffset;
514 __le32 patternsize;
515 __le32 id;
516 __le32 reasonsize;
517 __le32 type;
518 /* u8 mask[] - Mask follows the structure above */
519 /* u8 pattern[] - Pattern follows the mask is at 'patternoffset' */
520};
521
487#endif /* FWIL_TYPES_H_ */ 522#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 183f08d7fc8c..f0dda0ecd23b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -26,15 +26,15 @@
26 26
27#include <brcmu_utils.h> 27#include <brcmu_utils.h>
28#include <brcmu_wifi.h> 28#include <brcmu_wifi.h>
29#include "dhd.h" 29#include "core.h"
30#include "dhd_dbg.h" 30#include "debug.h"
31#include "dhd_bus.h" 31#include "bus.h"
32#include "fwil.h" 32#include "fwil.h"
33#include "fwil_types.h" 33#include "fwil_types.h"
34#include "fweh.h" 34#include "fweh.h"
35#include "fwsignal.h" 35#include "fwsignal.h"
36#include "p2p.h" 36#include "p2p.h"
37#include "wl_cfg80211.h" 37#include "cfg80211.h"
38#include "proto.h" 38#include "proto.h"
39 39
40/** 40/**
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 11cc051f97cd..9f783db34ae5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -24,13 +24,13 @@
24#include <brcmu_utils.h> 24#include <brcmu_utils.h>
25#include <brcmu_wifi.h> 25#include <brcmu_wifi.h>
26 26
27#include "dhd.h" 27#include "core.h"
28#include "dhd_dbg.h" 28#include "debug.h"
29#include "proto.h" 29#include "proto.h"
30#include "msgbuf.h" 30#include "msgbuf.h"
31#include "commonring.h" 31#include "commonring.h"
32#include "flowring.h" 32#include "flowring.h"
33#include "dhd_bus.h" 33#include "bus.h"
34#include "tracepoint.h" 34#include "tracepoint.h"
35 35
36 36
@@ -518,8 +518,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
518 memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? 518 memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ?
519 len : msgbuf->ioctl_resp_ret_len); 519 len : msgbuf->ioctl_resp_ret_len);
520 } 520 }
521 if (skb) 521 brcmu_pkt_buf_free_skb(skb);
522 brcmu_pkt_buf_free_skb(skb);
523 522
524 return msgbuf->ioctl_resp_status; 523 return msgbuf->ioctl_resp_status;
525} 524}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.c b/drivers/net/wireless/brcm80211/brcmfmac/of.c
index f05f5270fec1..eb3fce82a223 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c
@@ -21,8 +21,8 @@
21#include <linux/mmc/sdio_func.h> 21#include <linux/mmc/sdio_func.h>
22 22
23#include <defs.h> 23#include <defs.h>
24#include "dhd_dbg.h" 24#include "debug.h"
25#include "sdio_host.h" 25#include "sdio.h"
26 26
27void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) 27void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
28{ 28{
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index d54c58a32faa..effb48ebd864 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -21,12 +21,12 @@
21#include <brcmu_wifi.h> 21#include <brcmu_wifi.h>
22#include <brcmu_utils.h> 22#include <brcmu_utils.h>
23#include <defs.h> 23#include <defs.h>
24#include <dhd.h> 24#include "core.h"
25#include <dhd_dbg.h> 25#include "debug.h"
26#include "fwil.h" 26#include "fwil.h"
27#include "fwil_types.h" 27#include "fwil_types.h"
28#include "p2p.h" 28#include "p2p.h"
29#include "wl_cfg80211.h" 29#include "cfg80211.h"
30 30
31/* parameters used for p2p escan */ 31/* parameters used for p2p escan */
32#define P2PAPI_SCAN_NPROBES 1 32#define P2PAPI_SCAN_NPROBES 1
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
index 8c0632ec9f7a..b0ae7993e2e8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -30,8 +30,8 @@
30#include <brcmu_wifi.h> 30#include <brcmu_wifi.h>
31#include <brcm_hw_ids.h> 31#include <brcm_hw_ids.h>
32 32
33#include "dhd_dbg.h" 33#include "debug.h"
34#include "dhd_bus.h" 34#include "bus.h"
35#include "commonring.h" 35#include "commonring.h"
36#include "msgbuf.h" 36#include "msgbuf.h"
37#include "pcie.h" 37#include "pcie.h"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
index 62b940723339..26b68c367f57 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
@@ -20,9 +20,9 @@
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21 21
22#include <brcmu_wifi.h> 22#include <brcmu_wifi.h>
23#include "dhd.h" 23#include "core.h"
24#include "dhd_bus.h" 24#include "bus.h"
25#include "dhd_dbg.h" 25#include "debug.h"
26#include "proto.h" 26#include "proto.h"
27#include "bcdc.h" 27#include "bcdc.h"
28#include "msgbuf.h" 28#include "msgbuf.h"
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index f55f625fd06b..0b0d51a61060 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -40,7 +40,7 @@
40#include <brcmu_utils.h> 40#include <brcmu_utils.h>
41#include <brcm_hw_ids.h> 41#include <brcm_hw_ids.h>
42#include <soc.h> 42#include <soc.h>
43#include "sdio_host.h" 43#include "sdio.h"
44#include "chip.h" 44#include "chip.h"
45#include "firmware.h" 45#include "firmware.h"
46 46
@@ -96,8 +96,8 @@ struct rte_console {
96#endif /* DEBUG */ 96#endif /* DEBUG */
97#include <chipcommon.h> 97#include <chipcommon.h>
98 98
99#include "dhd_bus.h" 99#include "bus.h"
100#include "dhd_dbg.h" 100#include "debug.h"
101#include "tracepoint.h" 101#include "tracepoint.h"
102 102
103#define TXQLEN 2048 /* bulk tx queue length */ 103#define TXQLEN 2048 /* bulk tx queue length */
@@ -670,7 +670,6 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
670 struct brcmf_sdio_dev *sdiodev) 670 struct brcmf_sdio_dev *sdiodev)
671{ 671{
672 int i; 672 int i;
673 uint fw_len, nv_len;
674 char end; 673 char end;
675 674
676 for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) { 675 for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
@@ -684,25 +683,25 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
684 return -ENODEV; 683 return -ENODEV;
685 } 684 }
686 685
687 fw_len = sizeof(sdiodev->fw_name) - 1;
688 nv_len = sizeof(sdiodev->nvram_name) - 1;
689 /* check if firmware path is provided by module parameter */ 686 /* check if firmware path is provided by module parameter */
690 if (brcmf_firmware_path[0] != '\0') { 687 if (brcmf_firmware_path[0] != '\0') {
691 strncpy(sdiodev->fw_name, brcmf_firmware_path, fw_len); 688 strlcpy(sdiodev->fw_name, brcmf_firmware_path,
692 strncpy(sdiodev->nvram_name, brcmf_firmware_path, nv_len); 689 sizeof(sdiodev->fw_name));
693 fw_len -= strlen(sdiodev->fw_name); 690 strlcpy(sdiodev->nvram_name, brcmf_firmware_path,
694 nv_len -= strlen(sdiodev->nvram_name); 691 sizeof(sdiodev->nvram_name));
695 692
696 end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1]; 693 end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
697 if (end != '/') { 694 if (end != '/') {
698 strncat(sdiodev->fw_name, "/", fw_len); 695 strlcat(sdiodev->fw_name, "/",
699 strncat(sdiodev->nvram_name, "/", nv_len); 696 sizeof(sdiodev->fw_name));
700 fw_len--; 697 strlcat(sdiodev->nvram_name, "/",
701 nv_len--; 698 sizeof(sdiodev->nvram_name));
702 } 699 }
703 } 700 }
704 strncat(sdiodev->fw_name, brcmf_fwname_data[i].bin, fw_len); 701 strlcat(sdiodev->fw_name, brcmf_fwname_data[i].bin,
705 strncat(sdiodev->nvram_name, brcmf_fwname_data[i].nv, nv_len); 702 sizeof(sdiodev->fw_name));
703 strlcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv,
704 sizeof(sdiodev->nvram_name));
706 705
707 return 0; 706 return 0;
708} 707}
@@ -2763,6 +2762,48 @@ static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
2763 return &bus->txq; 2762 return &bus->txq;
2764} 2763}
2765 2764
2765static bool brcmf_sdio_prec_enq(struct pktq *q, struct sk_buff *pkt, int prec)
2766{
2767 struct sk_buff *p;
2768 int eprec = -1; /* precedence to evict from */
2769
2770 /* Fast case, precedence queue is not full and we are also not
2771 * exceeding total queue length
2772 */
2773 if (!pktq_pfull(q, prec) && !pktq_full(q)) {
2774 brcmu_pktq_penq(q, prec, pkt);
2775 return true;
2776 }
2777
2778 /* Determine precedence from which to evict packet, if any */
2779 if (pktq_pfull(q, prec)) {
2780 eprec = prec;
2781 } else if (pktq_full(q)) {
2782 p = brcmu_pktq_peek_tail(q, &eprec);
2783 if (eprec > prec)
2784 return false;
2785 }
2786
2787 /* Evict if needed */
2788 if (eprec >= 0) {
2789 /* Detect queueing to unconfigured precedence */
2790 if (eprec == prec)
2791 return false; /* refuse newer (incoming) packet */
2792 /* Evict packet according to discard policy */
2793 p = brcmu_pktq_pdeq_tail(q, eprec);
2794 if (p == NULL)
2795 brcmf_err("brcmu_pktq_pdeq_tail() failed\n");
2796 brcmu_pkt_buf_free_skb(p);
2797 }
2798
2799 /* Enqueue */
2800 p = brcmu_pktq_penq(q, prec, pkt);
2801 if (p == NULL)
2802 brcmf_err("brcmu_pktq_penq() failed\n");
2803
2804 return p != NULL;
2805}
2806
2766static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) 2807static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2767{ 2808{
2768 int ret = -EBADE; 2809 int ret = -EBADE;
@@ -2788,7 +2829,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2788 spin_lock_bh(&bus->txq_lock); 2829 spin_lock_bh(&bus->txq_lock);
2789 /* reset bus_flags in packet cb */ 2830 /* reset bus_flags in packet cb */
2790 *(u16 *)(pkt->cb) = 0; 2831 *(u16 *)(pkt->cb) = 0;
2791 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { 2832 if (!brcmf_sdio_prec_enq(&bus->txq, pkt, prec)) {
2792 skb_pull(pkt, bus->tx_hdrlen); 2833 skb_pull(pkt, bus->tx_hdrlen);
2793 brcmf_err("out of bus->txq !!!\n"); 2834 brcmf_err("out of bus->txq !!!\n");
2794 ret = -ENOSR; 2835 ret = -ENOSR;
@@ -2798,7 +2839,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2798 2839
2799 if (pktq_len(&bus->txq) >= TXHI) { 2840 if (pktq_len(&bus->txq) >= TXHI) {
2800 bus->txoff = true; 2841 bus->txoff = true;
2801 brcmf_txflowblock(bus->sdiodev->dev, true); 2842 brcmf_txflowblock(dev, true);
2802 } 2843 }
2803 spin_unlock_bh(&bus->txq_lock); 2844 spin_unlock_bh(&bus->txq_lock);
2804 2845
@@ -3949,6 +3990,7 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3949 .txctl = brcmf_sdio_bus_txctl, 3990 .txctl = brcmf_sdio_bus_txctl,
3950 .rxctl = brcmf_sdio_bus_rxctl, 3991 .rxctl = brcmf_sdio_bus_rxctl,
3951 .gettxq = brcmf_sdio_bus_gettxq, 3992 .gettxq = brcmf_sdio_bus_gettxq,
3993 .wowl_config = brcmf_sdio_wowl_config
3952}; 3994};
3953 3995
3954static void brcmf_sdio_firmware_callback(struct device *dev, 3996static void brcmf_sdio_firmware_callback(struct device *dev,
@@ -4075,7 +4117,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4075 4117
4076 /* platform specific configuration: 4118 /* platform specific configuration:
4077 * alignments must be at least 4 bytes for ADMA 4119 * alignments must be at least 4 bytes for ADMA
4078 */ 4120 */
4079 bus->head_align = ALIGNMENT; 4121 bus->head_align = ALIGNMENT;
4080 bus->sgentry_align = ALIGNMENT; 4122 bus->sgentry_align = ALIGNMENT;
4081 if (sdiodev->pdata) { 4123 if (sdiodev->pdata) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
index f2d06cae366a..8eb42620129c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
@@ -14,8 +14,8 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef _BRCM_SDH_H_ 17#ifndef BRCMFMAC_SDIO_H
18#define _BRCM_SDH_H_ 18#define BRCMFMAC_SDIO_H
19 19
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21#include <linux/firmware.h> 21#include <linux/firmware.h>
@@ -186,6 +186,7 @@ struct brcmf_sdio_dev {
186 struct sg_table sgtable; 186 struct sg_table sgtable;
187 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 187 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
188 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 188 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
189 bool wowl_enabled;
189}; 190};
190 191
191/* sdio core registers */ 192/* sdio core registers */
@@ -334,5 +335,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus);
334void brcmf_sdio_isr(struct brcmf_sdio *bus); 335void brcmf_sdio_isr(struct brcmf_sdio *bus);
335 336
336void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); 337void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
338void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
337 339
338#endif /* _BRCM_SDH_H_ */ 340#endif /* BRCMFMAC_SDIO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
index b505db48c60d..a10f35c5eb3d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
@@ -19,4 +19,19 @@
19#ifndef __CHECKER__ 19#ifndef __CHECKER__
20#define CREATE_TRACE_POINTS 20#define CREATE_TRACE_POINTS
21#include "tracepoint.h" 21#include "tracepoint.h"
22
23void __brcmf_err(const char *func, const char *fmt, ...)
24{
25 struct va_format vaf = {
26 .fmt = fmt,
27 };
28 va_list args;
29
30 va_start(args, fmt);
31 vaf.va = &args;
32 pr_err("%s: %pV", func, &vaf);
33 trace_brcmf_err(func, &vaf);
34 va_end(args);
35}
36
22#endif 37#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index dc135915470d..5265aa70b094 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -23,13 +23,12 @@
23#include <brcmu_utils.h> 23#include <brcmu_utils.h>
24#include <brcm_hw_ids.h> 24#include <brcm_hw_ids.h>
25#include <brcmu_wifi.h> 25#include <brcmu_wifi.h>
26#include <dhd_bus.h> 26#include "bus.h"
27#include <dhd_dbg.h> 27#include "debug.h"
28
29#include "firmware.h" 28#include "firmware.h"
30#include "usb_rdl.h"
31#include "usb.h" 29#include "usb.h"
32 30
31
33#define IOCTL_RESP_TIMEOUT 2000 32#define IOCTL_RESP_TIMEOUT 2000
34 33
35#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ 34#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */
@@ -49,6 +48,71 @@
49#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" 48#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
50#define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin" 49#define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin"
51 50
51#define TRX_MAGIC 0x30524448 /* "HDR0" */
52#define TRX_MAX_OFFSET 3 /* Max number of file offsets */
53#define TRX_UNCOMP_IMAGE 0x20 /* Trx holds uncompressed img */
54#define TRX_RDL_CHUNK 1500 /* size of each dl transfer */
55#define TRX_OFFSETS_DLFWLEN_IDX 0
56
57/* Control messages: bRequest values */
58#define DL_GETSTATE 0 /* returns the rdl_state_t struct */
59#define DL_CHECK_CRC 1 /* currently unused */
60#define DL_GO 2 /* execute downloaded image */
61#define DL_START 3 /* initialize dl state */
62#define DL_REBOOT 4 /* reboot the device in 2 seconds */
63#define DL_GETVER 5 /* returns the bootrom_id_t struct */
64#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset
65 * event to occur in 2 seconds. It is the
66 * responsibility of the downloaded code to
67 * clear this event
68 */
69#define DL_EXEC 7 /* jump to a supplied address */
70#define DL_RESETCFG 8 /* To support single enum on dongle
71 * - Not used by bootloader
72 */
73#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup
74 * if resp unavailable
75 */
76
77/* states */
78#define DL_WAITING 0 /* waiting to rx first pkt */
79#define DL_READY 1 /* hdr was good, waiting for more of the
80 * compressed image
81 */
82#define DL_BAD_HDR 2 /* hdr was corrupted */
83#define DL_BAD_CRC 3 /* compressed image was corrupted */
84#define DL_RUNNABLE 4 /* download was successful,waiting for go cmd */
85#define DL_START_FAIL 5 /* failed to initialize correctly */
86#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM
87 * value
88 */
89#define DL_IMAGE_TOOBIG 7 /* firmware image too big */
90
91
92struct trx_header_le {
93 __le32 magic; /* "HDR0" */
94 __le32 len; /* Length of file including header */
95 __le32 crc32; /* CRC from flag_version to end of file */
96 __le32 flag_version; /* 0:15 flags, 16:31 version */
97 __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of
98 * header
99 */
100};
101
102struct rdl_state_le {
103 __le32 state;
104 __le32 bytes;
105};
106
107struct bootrom_id_le {
108 __le32 chip; /* Chip id */
109 __le32 chiprev; /* Chip rev */
110 __le32 ramsize; /* Size of RAM */
111 __le32 remapbase; /* Current remap base address */
112 __le32 boardtype; /* Type of board */
113 __le32 boardrev; /* Board revision */
114};
115
52struct brcmf_usb_image { 116struct brcmf_usb_image {
53 struct list_head list; 117 struct list_head list;
54 s8 *fwname; 118 s8 *fwname;
@@ -93,6 +157,8 @@ struct brcmf_usbdev_info {
93 u8 ifnum; 157 u8 ifnum;
94 158
95 struct urb *bulk_urb; /* used for FW download */ 159 struct urb *bulk_urb; /* used for FW download */
160
161 bool wowl_enabled;
96}; 162};
97 163
98static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, 164static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
@@ -600,6 +666,16 @@ static int brcmf_usb_up(struct device *dev)
600 return 0; 666 return 0;
601} 667}
602 668
669static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo)
670{
671 if (devinfo->ctl_urb)
672 usb_kill_urb(devinfo->ctl_urb);
673 if (devinfo->bulk_urb)
674 usb_kill_urb(devinfo->bulk_urb);
675 brcmf_usb_free_q(&devinfo->tx_postq, true);
676 brcmf_usb_free_q(&devinfo->rx_postq, true);
677}
678
603static void brcmf_usb_down(struct device *dev) 679static void brcmf_usb_down(struct device *dev)
604{ 680{
605 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 681 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
@@ -613,14 +689,7 @@ static void brcmf_usb_down(struct device *dev)
613 689
614 brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN); 690 brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);
615 691
616 if (devinfo->ctl_urb) 692 brcmf_cancel_all_urbs(devinfo);
617 usb_kill_urb(devinfo->ctl_urb);
618
619 if (devinfo->bulk_urb)
620 usb_kill_urb(devinfo->bulk_urb);
621 brcmf_usb_free_q(&devinfo->tx_postq, true);
622
623 brcmf_usb_free_q(&devinfo->rx_postq, true);
624} 693}
625 694
626static void 695static void
@@ -783,7 +852,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
783 852
784 brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen); 853 brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen);
785 854
786 bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); 855 bulkchunk = kmalloc(TRX_RDL_CHUNK, GFP_ATOMIC);
787 if (bulkchunk == NULL) { 856 if (bulkchunk == NULL) {
788 err = -ENOMEM; 857 err = -ENOMEM;
789 goto fail; 858 goto fail;
@@ -810,10 +879,10 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
810 /* Wait until the usb device reports it received all 879 /* Wait until the usb device reports it received all
811 * the bytes we sent */ 880 * the bytes we sent */
812 if ((rdlbytes == sent) && (rdlbytes != dllen)) { 881 if ((rdlbytes == sent) && (rdlbytes != dllen)) {
813 if ((dllen-sent) < RDL_CHUNK) 882 if ((dllen-sent) < TRX_RDL_CHUNK)
814 sendlen = dllen-sent; 883 sendlen = dllen-sent;
815 else 884 else
816 sendlen = RDL_CHUNK; 885 sendlen = TRX_RDL_CHUNK;
817 886
818 /* simply avoid having to send a ZLP by ensuring we 887 /* simply avoid having to send a ZLP by ensuring we
819 * never have an even 888 * never have an even
@@ -978,21 +1047,6 @@ static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
978 kfree(devinfo->rx_reqs); 1047 kfree(devinfo->rx_reqs);
979} 1048}
980 1049
981#define TRX_MAGIC 0x30524448 /* "HDR0" */
982#define TRX_VERSION 1 /* Version 1 */
983#define TRX_MAX_LEN 0x3B0000 /* Max length */
984#define TRX_NO_HEADER 1 /* Do not write TRX header */
985#define TRX_MAX_OFFSET 3 /* Max number of individual files */
986#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed image */
987
988struct trx_header_le {
989 __le32 magic; /* "HDR0" */
990 __le32 len; /* Length of file including header */
991 __le32 crc32; /* CRC from flag_version to end of file */
992 __le32 flag_version; /* 0:15 flags, 16:31 version */
993 __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of
994 * header */
995};
996 1050
997static int check_file(const u8 *headers) 1051static int check_file(const u8 *headers)
998{ 1052{
@@ -1094,11 +1148,24 @@ error:
1094 return NULL; 1148 return NULL;
1095} 1149}
1096 1150
1151static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
1152{
1153 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
1154
1155 brcmf_dbg(USB, "Configuring WOWL, enabled=%d\n", enabled);
1156 devinfo->wowl_enabled = enabled;
1157 if (enabled)
1158 device_set_wakeup_enable(devinfo->dev, true);
1159 else
1160 device_set_wakeup_enable(devinfo->dev, false);
1161}
1162
1097static struct brcmf_bus_ops brcmf_usb_bus_ops = { 1163static struct brcmf_bus_ops brcmf_usb_bus_ops = {
1098 .txdata = brcmf_usb_tx, 1164 .txdata = brcmf_usb_tx,
1099 .stop = brcmf_usb_down, 1165 .stop = brcmf_usb_down,
1100 .txctl = brcmf_usb_tx_ctlpkt, 1166 .txctl = brcmf_usb_tx_ctlpkt,
1101 .rxctl = brcmf_usb_rx_ctlpkt, 1167 .rxctl = brcmf_usb_rx_ctlpkt,
1168 .wowl_config = brcmf_usb_wowl_config,
1102}; 1169};
1103 1170
1104static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) 1171static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
@@ -1186,6 +1253,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1186 bus->ops = &brcmf_usb_bus_ops; 1253 bus->ops = &brcmf_usb_bus_ops;
1187 bus->proto_type = BRCMF_PROTO_BCDC; 1254 bus->proto_type = BRCMF_PROTO_BCDC;
1188 bus->always_use_fws_queue = true; 1255 bus->always_use_fws_queue = true;
1256#ifdef CONFIG_PM
1257 bus->wowl_supported = true;
1258#endif
1189 1259
1190 if (!brcmf_usb_dlneeded(devinfo)) { 1260 if (!brcmf_usb_dlneeded(devinfo)) {
1191 ret = brcmf_usb_bus_setup(devinfo); 1261 ret = brcmf_usb_bus_setup(devinfo);
@@ -1339,7 +1409,10 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
1339 1409
1340 brcmf_dbg(USB, "Enter\n"); 1410 brcmf_dbg(USB, "Enter\n");
1341 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; 1411 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
1342 brcmf_detach(&usb->dev); 1412 if (devinfo->wowl_enabled)
1413 brcmf_cancel_all_urbs(devinfo);
1414 else
1415 brcmf_detach(&usb->dev);
1343 return 0; 1416 return 0;
1344} 1417}
1345 1418
@@ -1352,7 +1425,12 @@ static int brcmf_usb_resume(struct usb_interface *intf)
1352 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1425 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1353 1426
1354 brcmf_dbg(USB, "Enter\n"); 1427 brcmf_dbg(USB, "Enter\n");
1355 return brcmf_usb_bus_setup(devinfo); 1428 if (!devinfo->wowl_enabled)
1429 return brcmf_usb_bus_setup(devinfo);
1430
1431 devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP;
1432 brcmf_usb_rx_fill_all(devinfo);
1433 return 0;
1356} 1434}
1357 1435
1358static int brcmf_usb_reset_resume(struct usb_interface *intf) 1436static int brcmf_usb_reset_resume(struct usb_interface *intf)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
deleted file mode 100644
index 0a35c51c3da2..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _USB_RDL_H
18#define _USB_RDL_H
19
20/* Control messages: bRequest values */
21#define DL_GETSTATE 0 /* returns the rdl_state_t struct */
22#define DL_CHECK_CRC 1 /* currently unused */
23#define DL_GO 2 /* execute downloaded image */
24#define DL_START 3 /* initialize dl state */
25#define DL_REBOOT 4 /* reboot the device in 2 seconds */
26#define DL_GETVER 5 /* returns the bootrom_id_t struct */
27#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset
28 * event to occur in 2 seconds. It is the
29 * responsibility of the downloaded code to
30 * clear this event
31 */
32#define DL_EXEC 7 /* jump to a supplied address */
33#define DL_RESETCFG 8 /* To support single enum on dongle
34 * - Not used by bootloader
35 */
36#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup
37 * if resp unavailable
38 */
39
40/* states */
41#define DL_WAITING 0 /* waiting to rx first pkt */
42#define DL_READY 1 /* hdr was good, waiting for more of the
43 * compressed image */
44#define DL_BAD_HDR 2 /* hdr was corrupted */
45#define DL_BAD_CRC 3 /* compressed image was corrupted */
46#define DL_RUNNABLE 4 /* download was successful,waiting for go cmd */
47#define DL_START_FAIL 5 /* failed to initialize correctly */
48#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM
49 * value */
50#define DL_IMAGE_TOOBIG 7 /* download image too big (exceeds DATA_START
51 * for rdl) */
52
53struct rdl_state_le {
54 __le32 state;
55 __le32 bytes;
56};
57
58struct bootrom_id_le {
59 __le32 chip; /* Chip id */
60 __le32 chiprev; /* Chip rev */
61 __le32 ramsize; /* Size of RAM */
62 __le32 remapbase; /* Current remap base address */
63 __le32 boardtype; /* Type of board */
64 __le32 boardrev; /* Board revision */
65};
66
67#define RDL_CHUNK 1500 /* size of each dl transfer */
68
69#define TRX_OFFSETS_DLFWLEN_IDX 0
70#define TRX_OFFSETS_JUMPTO_IDX 1
71#define TRX_OFFSETS_NVM_LEN_IDX 2
72
73#define TRX_OFFSETS_DLBASE_IDX 0
74
75#endif /* _USB_RDL_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
index 5960d827508c..222f26a39642 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
@@ -20,10 +20,10 @@
20 20
21#include <brcmu_wifi.h> 21#include <brcmu_wifi.h>
22#include "fwil_types.h" 22#include "fwil_types.h"
23#include "dhd.h" 23#include "core.h"
24#include "p2p.h" 24#include "p2p.h"
25#include "dhd_dbg.h" 25#include "debug.h"
26#include "wl_cfg80211.h" 26#include "cfg80211.h"
27#include "vendor.h" 27#include "vendor.h"
28#include "fwil.h" 28#include "fwil.h"
29 29