aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-02-18 13:47:13 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-02-18 13:47:13 -0500
commit98d5fac2330779e6eea6431a90b44c7476260dcc (patch)
tree99870656d835fc6c12093bc67517956cc7b3d6ec /drivers/net/wireless/brcm80211
parent4153577a8d318ae02b3791341e10e78416de402f (diff)
parent9e97d14b4923da524d202f2e005d5d30b70db9d6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/iwlwifi/dvm/tx.c drivers/net/wireless/ti/wlcore/sdio.c drivers/net/wireless/ti/wlcore/spi.c
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h19
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c311
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c25
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h66
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c2277
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.h183
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1369
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h113
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c65
17 files changed, 3940 insertions, 594 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 1a6661a9f008..756e19fc2795 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -26,6 +26,7 @@ brcmfmac-objs += \
26 wl_cfg80211.o \ 26 wl_cfg80211.o \
27 fwil.o \ 27 fwil.o \
28 fweh.o \ 28 fweh.o \
29 p2p.o \
29 dhd_cdc.o \ 30 dhd_cdc.o \
30 dhd_common.o \ 31 dhd_common.o \
31 dhd_linux.o 32 dhd_linux.o
@@ -37,4 +38,4 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
37brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ 38brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
38 usb.o 39 usb.o
39brcmfmac-$(CONFIG_BRCMDBG) += \ 40brcmfmac-$(CONFIG_BRCMDBG) += \
40 dhd_dbg.o \ No newline at end of file 41 dhd_dbg.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index a2f32fb990fa..ef6f23be6d32 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -72,6 +72,7 @@
72#define BRCMF_C_SET_WSEC 134 72#define BRCMF_C_SET_WSEC 134
73#define BRCMF_C_GET_PHY_NOISE 135 73#define BRCMF_C_GET_PHY_NOISE 135
74#define BRCMF_C_GET_BSS_INFO 136 74#define BRCMF_C_GET_BSS_INFO 136
75#define BRCMF_C_SET_SCB_TIMEOUT 158
75#define BRCMF_C_GET_PHYLIST 180 76#define BRCMF_C_GET_PHYLIST 180
76#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 77#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
77#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 78#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
@@ -149,6 +150,7 @@
149#define BRCMF_E_REASON_MINTXRATE 9 150#define BRCMF_E_REASON_MINTXRATE 9
150#define BRCMF_E_REASON_TXFAIL 10 151#define BRCMF_E_REASON_TXFAIL 10
151 152
153#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
152#define BRCMF_E_REASON_FAST_ROAM_FAILED 5 154#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
153#define BRCMF_E_REASON_DIRECTED_ROAM 6 155#define BRCMF_E_REASON_DIRECTED_ROAM 6
154#define BRCMF_E_REASON_TSPEC_REJECTED 7 156#define BRCMF_E_REASON_TSPEC_REJECTED 7
@@ -375,6 +377,28 @@ struct brcmf_join_params {
375 struct brcmf_assoc_params_le params_le; 377 struct brcmf_assoc_params_le params_le;
376}; 378};
377 379
380/* scan params for extended join */
381struct brcmf_join_scan_params_le {
382 u8 scan_type; /* 0 use default, active or passive scan */
383 __le32 nprobes; /* -1 use default, nr of probes per channel */
384 __le32 active_time; /* -1 use default, dwell time per channel for
385 * active scanning
386 */
387 __le32 passive_time; /* -1 use default, dwell time per channel
388 * for passive scanning
389 */
390 __le32 home_time; /* -1 use default, dwell time for the home
391 * channel between channel scans
392 */
393};
394
395/* extended join params */
396struct brcmf_ext_join_params_le {
397 struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
398 struct brcmf_join_scan_params_le scan_le;
399 struct brcmf_assoc_params_le assoc_le;
400};
401
378struct brcmf_wsec_key { 402struct brcmf_wsec_key {
379 u32 index; /* key index */ 403 u32 index; /* key index */
380 u32 len; /* key length */ 404 u32 len; /* key length */
@@ -451,6 +475,19 @@ struct brcmf_sta_info_le {
451 __le32 rx_decrypt_failures; /* # of packet decrypted failed */ 475 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
452}; 476};
453 477
478/*
479 * WLC_E_PROBRESP_MSG
480 * WLC_E_P2P_PROBREQ_MSG
481 * WLC_E_ACTION_FRAME_RX
482 */
483struct brcmf_rx_mgmt_data {
484 __be16 version;
485 __be16 chanspec;
486 __be32 rssi;
487 __be32 mactime;
488 __be32 rate;
489};
490
454/* Bus independent dongle command */ 491/* Bus independent dongle command */
455struct brcmf_dcmd { 492struct brcmf_dcmd {
456 uint cmd; /* common dongle cmd definition */ 493 uint cmd; /* common dongle cmd definition */
@@ -489,9 +526,6 @@ struct brcmf_pub {
489 struct mutex proto_block; 526 struct mutex proto_block;
490 unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; 527 unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
491 528
492 atomic_t pend_8021x_cnt;
493 wait_queue_head_t pend_8021x_wait;
494
495 struct brcmf_fweh_info fweh; 529 struct brcmf_fweh_info fweh;
496#ifdef DEBUG 530#ifdef DEBUG
497 struct dentry *dbgfs_dir; 531 struct dentry *dbgfs_dir;
@@ -515,9 +549,11 @@ struct brcmf_cfg80211_vif;
515 * @vif: points to cfg80211 specific interface information. 549 * @vif: points to cfg80211 specific interface information.
516 * @ndev: associated network device. 550 * @ndev: associated network device.
517 * @stats: interface specific network statistics. 551 * @stats: interface specific network statistics.
518 * @idx: interface index in device firmware. 552 * @ifidx: interface index in device firmware.
519 * @bssidx: index of bss associated with this interface. 553 * @bssidx: index of bss associated with this interface.
520 * @mac_addr: assigned mac address. 554 * @mac_addr: assigned mac address.
555 * @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
556 * @pend_8021x_wait: used for signalling change in count.
521 */ 557 */
522struct brcmf_if { 558struct brcmf_if {
523 struct brcmf_pub *drvr; 559 struct brcmf_pub *drvr;
@@ -526,9 +562,11 @@ struct brcmf_if {
526 struct net_device_stats stats; 562 struct net_device_stats stats;
527 struct work_struct setmacaddr_work; 563 struct work_struct setmacaddr_work;
528 struct work_struct multicast_work; 564 struct work_struct multicast_work;
529 int idx; 565 int ifidx;
530 s32 bssidx; 566 s32 bssidx;
531 u8 mac_addr[ETH_ALEN]; 567 u8 mac_addr[ETH_ALEN];
568 atomic_t pend_8021x_cnt;
569 wait_queue_head_t pend_8021x_wait;
532}; 570};
533 571
534 572
@@ -547,9 +585,10 @@ extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
547extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, 585extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
548 struct sk_buff *rxp); 586 struct sk_buff *rxp);
549 587
550extern int brcmf_net_attach(struct brcmf_if *ifp); 588extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
551extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, 589extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx,
552 s32 bssidx, char *name, u8 *mac_addr); 590 s32 ifidx, char *name, u8 *mac_addr);
553extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); 591extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
592extern u32 brcmf_get_chip_info(struct brcmf_if *ifp);
554 593
555#endif /* _BRCMF_H_ */ 594#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 64c38f4226a3..ad25c3408b59 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -24,18 +24,6 @@ enum brcmf_bus_state {
24 BRCMF_BUS_DATA /* Ready for frame transfers */ 24 BRCMF_BUS_DATA /* Ready for frame transfers */
25}; 25};
26 26
27struct dngl_stats {
28 unsigned long rx_packets; /* total packets received */
29 unsigned long tx_packets; /* total packets transmitted */
30 unsigned long rx_bytes; /* total bytes received */
31 unsigned long tx_bytes; /* total bytes transmitted */
32 unsigned long rx_errors; /* bad packets received */
33 unsigned long tx_errors; /* packet transmit problems */
34 unsigned long rx_dropped; /* packets dropped by dongle */
35 unsigned long tx_dropped; /* packets dropped by dongle */
36 unsigned long multicast; /* multicast packets received */
37};
38
39struct brcmf_bus_dcmd { 27struct brcmf_bus_dcmd {
40 char *name; 28 char *name;
41 char *param; 29 char *param;
@@ -72,11 +60,12 @@ struct brcmf_bus_ops {
72 * @drvr: public driver information. 60 * @drvr: public driver information.
73 * @state: operational state of the bus interface. 61 * @state: operational state of the bus interface.
74 * @maxctl: maximum size for rxctl request message. 62 * @maxctl: maximum size for rxctl request message.
75 * @drvr_up: indicates driver up/down status.
76 * @tx_realloc: number of tx packets realloced for headroom. 63 * @tx_realloc: number of tx packets realloced for headroom.
77 * @dstats: dongle-based statistical data. 64 * @dstats: dongle-based statistical data.
78 * @align: alignment requirement for the bus. 65 * @align: alignment requirement for the bus.
79 * @dcmd_list: bus/device specific dongle initialization commands. 66 * @dcmd_list: bus/device specific dongle initialization commands.
67 * @chip: device identifier of the dongle chip.
68 * @chiprev: revision of the dongle chip.
80 */ 69 */
81struct brcmf_bus { 70struct brcmf_bus {
82 union { 71 union {
@@ -87,10 +76,10 @@ struct brcmf_bus {
87 struct brcmf_pub *drvr; 76 struct brcmf_pub *drvr;
88 enum brcmf_bus_state state; 77 enum brcmf_bus_state state;
89 uint maxctl; 78 uint maxctl;
90 bool drvr_up;
91 unsigned long tx_realloc; 79 unsigned long tx_realloc;
92 struct dngl_stats dstats;
93 u8 align; 80 u8 align;
81 u32 chip;
82 u32 chiprev;
94 struct list_head dcmd_list; 83 struct list_head dcmd_list;
95 84
96 struct brcmf_bus_ops *ops; 85 struct brcmf_bus_ops *ops;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index bb454cdab29d..a2354d951dd7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -303,6 +303,14 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
303 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); 303 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
304 return -EBADE; 304 return -EBADE;
305 } 305 }
306 /* The ifidx is the idx to map to matching netdev/ifp. When receiving
307 * events this is easy because it contains the bssidx which maps
308 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
309 * bssidx 1 is used for p2p0 and no data can be received or
310 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
311 */
312 if (*ifidx)
313 (*ifidx)++;
306 314
307 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != 315 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
308 BDC_PROTO_VER) { 316 BDC_PROTO_VER) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 14b8fdde6954..c06cea88df0d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -26,6 +26,8 @@
26#include "dhd_bus.h" 26#include "dhd_bus.h"
27#include "dhd_proto.h" 27#include "dhd_proto.h"
28#include "dhd_dbg.h" 28#include "dhd_dbg.h"
29#include "fwil_types.h"
30#include "p2p.h"
29#include "wl_cfg80211.h" 31#include "wl_cfg80211.h"
30#include "fwil.h" 32#include "fwil.h"
31 33
@@ -40,6 +42,12 @@ MODULE_LICENSE("Dual BSD/GPL");
40int brcmf_msg_level; 42int brcmf_msg_level;
41module_param(brcmf_msg_level, int, 0); 43module_param(brcmf_msg_level, int, 0);
42 44
45/* P2P0 enable */
46static int brcmf_p2p_enable;
47#ifdef CONFIG_BRCMDBG
48module_param_named(p2pon, brcmf_p2p_enable, int, 0);
49MODULE_PARM_DESC(p2pon, "enable p2p management functionality");
50#endif
43 51
44char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) 52char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
45{ 53{
@@ -70,9 +78,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
70 u32 buflen; 78 u32 buflen;
71 s32 err; 79 s32 err;
72 80
73 brcmf_dbg(TRACE, "enter\n");
74
75 ifp = container_of(work, struct brcmf_if, multicast_work); 81 ifp = container_of(work, struct brcmf_if, multicast_work);
82
83 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
84
76 ndev = ifp->ndev; 85 ndev = ifp->ndev;
77 86
78 /* Determine initial value of allmulti flag */ 87 /* Determine initial value of allmulti flag */
@@ -129,9 +138,10 @@ _brcmf_set_mac_address(struct work_struct *work)
129 struct brcmf_if *ifp; 138 struct brcmf_if *ifp;
130 s32 err; 139 s32 err;
131 140
132 brcmf_dbg(TRACE, "enter\n");
133
134 ifp = container_of(work, struct brcmf_if, setmacaddr_work); 141 ifp = container_of(work, struct brcmf_if, setmacaddr_work);
142
143 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
144
135 err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, 145 err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
136 ETH_ALEN); 146 ETH_ALEN);
137 if (err < 0) { 147 if (err < 0) {
@@ -168,7 +178,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
168 struct brcmf_pub *drvr = ifp->drvr; 178 struct brcmf_pub *drvr = ifp->drvr;
169 struct ethhdr *eh; 179 struct ethhdr *eh;
170 180
171 brcmf_dbg(TRACE, "Enter\n"); 181 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
172 182
173 /* Can the device send data? */ 183 /* Can the device send data? */
174 if (drvr->bus_if->state != BRCMF_BUS_DATA) { 184 if (drvr->bus_if->state != BRCMF_BUS_DATA) {
@@ -179,8 +189,8 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
179 goto done; 189 goto done;
180 } 190 }
181 191
182 if (!drvr->iflist[ifp->idx]) { 192 if (!drvr->iflist[ifp->bssidx]) {
183 brcmf_err("bad ifidx %d\n", ifp->idx); 193 brcmf_err("bad ifidx %d\n", ifp->bssidx);
184 netif_stop_queue(ndev); 194 netif_stop_queue(ndev);
185 dev_kfree_skb(skb); 195 dev_kfree_skb(skb);
186 ret = -ENODEV; 196 ret = -ENODEV;
@@ -192,14 +202,14 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
192 struct sk_buff *skb2; 202 struct sk_buff *skb2;
193 203
194 brcmf_dbg(INFO, "%s: insufficient headroom\n", 204 brcmf_dbg(INFO, "%s: insufficient headroom\n",
195 brcmf_ifname(drvr, ifp->idx)); 205 brcmf_ifname(drvr, ifp->bssidx));
196 drvr->bus_if->tx_realloc++; 206 drvr->bus_if->tx_realloc++;
197 skb2 = skb_realloc_headroom(skb, drvr->hdrlen); 207 skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
198 dev_kfree_skb(skb); 208 dev_kfree_skb(skb);
199 skb = skb2; 209 skb = skb2;
200 if (skb == NULL) { 210 if (skb == NULL) {
201 brcmf_err("%s: skb_realloc_headroom failed\n", 211 brcmf_err("%s: skb_realloc_headroom failed\n",
202 brcmf_ifname(drvr, ifp->idx)); 212 brcmf_ifname(drvr, ifp->bssidx));
203 ret = -ENOMEM; 213 ret = -ENOMEM;
204 goto done; 214 goto done;
205 } 215 }
@@ -217,19 +227,21 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
217 if (is_multicast_ether_addr(eh->h_dest)) 227 if (is_multicast_ether_addr(eh->h_dest))
218 drvr->tx_multicast++; 228 drvr->tx_multicast++;
219 if (ntohs(eh->h_proto) == ETH_P_PAE) 229 if (ntohs(eh->h_proto) == ETH_P_PAE)
220 atomic_inc(&drvr->pend_8021x_cnt); 230 atomic_inc(&ifp->pend_8021x_cnt);
221 231
222 /* If the protocol uses a data header, apply it */ 232 /* If the protocol uses a data header, apply it */
223 brcmf_proto_hdrpush(drvr, ifp->idx, skb); 233 brcmf_proto_hdrpush(drvr, ifp->ifidx, skb);
224 234
225 /* Use bus module to send data frame */ 235 /* Use bus module to send data frame */
226 ret = brcmf_bus_txdata(drvr->bus_if, skb); 236 ret = brcmf_bus_txdata(drvr->bus_if, skb);
227 237
228done: 238done:
229 if (ret) 239 if (ret) {
230 drvr->bus_if->dstats.tx_dropped++; 240 ifp->stats.tx_dropped++;
231 else 241 } else {
232 drvr->bus_if->dstats.tx_packets++; 242 ifp->stats.tx_packets++;
243 ifp->stats.tx_bytes += skb->len;
244 }
233 245
234 /* Return ok: we always eat the packet */ 246 /* Return ok: we always eat the packet */
235 return NETDEV_TX_OK; 247 return NETDEV_TX_OK;
@@ -270,12 +282,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
270 skb_queue_walk_safe(skb_list, skb, pnext) { 282 skb_queue_walk_safe(skb_list, skb, pnext) {
271 skb_unlink(skb, skb_list); 283 skb_unlink(skb, skb_list);
272 284
273 /* process and remove protocol-specific header 285 /* process and remove protocol-specific header */
274 */
275 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); 286 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
276 if (ret < 0) { 287 ifp = drvr->iflist[ifidx];
277 if (ret != -ENODATA) 288
278 bus_if->dstats.rx_errors++; 289 if (ret || !ifp || !ifp->ndev) {
290 if ((ret != -ENODATA) && ifp)
291 ifp->stats.rx_errors++;
279 brcmu_pkt_buf_free_skb(skb); 292 brcmu_pkt_buf_free_skb(skb);
280 continue; 293 continue;
281 } 294 }
@@ -295,21 +308,11 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
295 eth = skb->data; 308 eth = skb->data;
296 len = skb->len; 309 len = skb->len;
297 310
298 ifp = drvr->iflist[ifidx];
299 if (ifp == NULL)
300 ifp = drvr->iflist[0];
301
302 if (!ifp || !ifp->ndev ||
303 ifp->ndev->reg_state != NETREG_REGISTERED) {
304 brcmu_pkt_buf_free_skb(skb);
305 continue;
306 }
307
308 skb->dev = ifp->ndev; 311 skb->dev = ifp->ndev;
309 skb->protocol = eth_type_trans(skb, skb->dev); 312 skb->protocol = eth_type_trans(skb, skb->dev);
310 313
311 if (skb->pkt_type == PACKET_MULTICAST) 314 if (skb->pkt_type == PACKET_MULTICAST)
312 bus_if->dstats.multicast++; 315 ifp->stats.multicast++;
313 316
314 skb->data = eth; 317 skb->data = eth;
315 skb->len = len; 318 skb->len = len;
@@ -325,8 +328,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
325 ifp->ndev->last_rx = jiffies; 328 ifp->ndev->last_rx = jiffies;
326 } 329 }
327 330
328 bus_if->dstats.rx_bytes += skb->len; 331 if (!(ifp->ndev->flags & IFF_UP)) {
329 bus_if->dstats.rx_packets++; /* Local count */ 332 brcmu_pkt_buf_free_skb(skb);
333 continue;
334 }
335
336 ifp->stats.rx_bytes += skb->len;
337 ifp->stats.rx_packets++;
330 338
331 if (in_interrupt()) 339 if (in_interrupt())
332 netif_rx(skb); 340 netif_rx(skb);
@@ -348,36 +356,31 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
348 u16 type; 356 u16 type;
349 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 357 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
350 struct brcmf_pub *drvr = bus_if->drvr; 358 struct brcmf_pub *drvr = bus_if->drvr;
359 struct brcmf_if *ifp;
351 360
352 brcmf_proto_hdrpull(drvr, &ifidx, txp); 361 brcmf_proto_hdrpull(drvr, &ifidx, txp);
353 362
363 ifp = drvr->iflist[ifidx];
364 if (!ifp)
365 return;
366
354 eh = (struct ethhdr *)(txp->data); 367 eh = (struct ethhdr *)(txp->data);
355 type = ntohs(eh->h_proto); 368 type = ntohs(eh->h_proto);
356 369
357 if (type == ETH_P_PAE) { 370 if (type == ETH_P_PAE) {
358 atomic_dec(&drvr->pend_8021x_cnt); 371 atomic_dec(&ifp->pend_8021x_cnt);
359 if (waitqueue_active(&drvr->pend_8021x_wait)) 372 if (waitqueue_active(&ifp->pend_8021x_wait))
360 wake_up(&drvr->pend_8021x_wait); 373 wake_up(&ifp->pend_8021x_wait);
361 } 374 }
375 if (!success)
376 ifp->stats.tx_errors++;
362} 377}
363 378
364static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 379static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
365{ 380{
366 struct brcmf_if *ifp = netdev_priv(ndev); 381 struct brcmf_if *ifp = netdev_priv(ndev);
367 struct brcmf_bus *bus_if = ifp->drvr->bus_if;
368
369 brcmf_dbg(TRACE, "Enter\n");
370 382
371 /* Copy dongle stats to net device stats */ 383 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
372 ifp->stats.rx_packets = bus_if->dstats.rx_packets;
373 ifp->stats.tx_packets = bus_if->dstats.tx_packets;
374 ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
375 ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
376 ifp->stats.rx_errors = bus_if->dstats.rx_errors;
377 ifp->stats.tx_errors = bus_if->dstats.tx_errors;
378 ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
379 ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
380 ifp->stats.multicast = bus_if->dstats.multicast;
381 384
382 return &ifp->stats; 385 return &ifp->stats;
383} 386}
@@ -431,7 +434,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
431 u32 toe_cmpnt, csum_dir; 434 u32 toe_cmpnt, csum_dir;
432 int ret; 435 int ret;
433 436
434 brcmf_dbg(TRACE, "Enter\n"); 437 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
435 438
436 /* all ethtool calls start with a cmd word */ 439 /* all ethtool calls start with a cmd word */
437 if (copy_from_user(&cmd, uaddr, sizeof(u32))) 440 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
@@ -454,13 +457,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
454 sprintf(info.driver, "dhd"); 457 sprintf(info.driver, "dhd");
455 strcpy(info.version, BRCMF_VERSION_STR); 458 strcpy(info.version, BRCMF_VERSION_STR);
456 } 459 }
457 460 /* report dongle driver type */
458 /* otherwise, require dongle to be up */
459 else if (!drvr->bus_if->drvr_up) {
460 brcmf_err("dongle is not up\n");
461 return -ENODEV;
462 }
463 /* finally, report dongle driver type */
464 else 461 else
465 sprintf(info.driver, "wl"); 462 sprintf(info.driver, "wl");
466 463
@@ -534,9 +531,9 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
534 struct brcmf_if *ifp = netdev_priv(ndev); 531 struct brcmf_if *ifp = netdev_priv(ndev);
535 struct brcmf_pub *drvr = ifp->drvr; 532 struct brcmf_pub *drvr = ifp->drvr;
536 533
537 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); 534 brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
538 535
539 if (!drvr->iflist[ifp->idx]) 536 if (!drvr->iflist[ifp->bssidx])
540 return -1; 537 return -1;
541 538
542 if (cmd == SIOCETHTOOL) 539 if (cmd == SIOCETHTOOL)
@@ -548,17 +545,12 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
548static int brcmf_netdev_stop(struct net_device *ndev) 545static int brcmf_netdev_stop(struct net_device *ndev)
549{ 546{
550 struct brcmf_if *ifp = netdev_priv(ndev); 547 struct brcmf_if *ifp = netdev_priv(ndev);
551 struct brcmf_pub *drvr = ifp->drvr;
552
553 brcmf_dbg(TRACE, "Enter\n");
554 548
555 if (drvr->bus_if->drvr_up == 0) 549 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
556 return 0;
557 550
558 brcmf_cfg80211_down(ndev); 551 brcmf_cfg80211_down(ndev);
559 552
560 /* Set state and stop OS transmissions */ 553 /* Set state and stop OS transmissions */
561 drvr->bus_if->drvr_up = false;
562 netif_stop_queue(ndev); 554 netif_stop_queue(ndev);
563 555
564 return 0; 556 return 0;
@@ -572,7 +564,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
572 u32 toe_ol; 564 u32 toe_ol;
573 s32 ret = 0; 565 s32 ret = 0;
574 566
575 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); 567 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
576 568
577 /* If bus is not ready, can't continue */ 569 /* If bus is not ready, can't continue */
578 if (bus_if->state != BRCMF_BUS_DATA) { 570 if (bus_if->state != BRCMF_BUS_DATA) {
@@ -580,9 +572,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
580 return -EAGAIN; 572 return -EAGAIN;
581 } 573 }
582 574
583 atomic_set(&drvr->pend_8021x_cnt, 0); 575 atomic_set(&ifp->pend_8021x_cnt, 0);
584
585 memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
586 576
587 /* Get current TOE mode from dongle */ 577 /* Get current TOE mode from dongle */
588 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 578 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
@@ -593,7 +583,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
593 583
594 /* Allow transmit calls */ 584 /* Allow transmit calls */
595 netif_start_queue(ndev); 585 netif_start_queue(ndev);
596 drvr->bus_if->drvr_up = true;
597 if (brcmf_cfg80211_up(ndev)) { 586 if (brcmf_cfg80211_up(ndev)) {
598 brcmf_err("failed to bring up cfg80211\n"); 587 brcmf_err("failed to bring up cfg80211\n");
599 return -1; 588 return -1;
@@ -612,29 +601,18 @@ static const struct net_device_ops brcmf_netdev_ops_pri = {
612 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 601 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
613}; 602};
614 603
615static const struct net_device_ops brcmf_netdev_ops_virt = { 604int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
616 .ndo_open = brcmf_cfg80211_up,
617 .ndo_stop = brcmf_cfg80211_down,
618 .ndo_get_stats = brcmf_netdev_get_stats,
619 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
620 .ndo_start_xmit = brcmf_netdev_start_xmit,
621 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
622 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
623};
624
625int brcmf_net_attach(struct brcmf_if *ifp)
626{ 605{
627 struct brcmf_pub *drvr = ifp->drvr; 606 struct brcmf_pub *drvr = ifp->drvr;
628 struct net_device *ndev; 607 struct net_device *ndev;
608 s32 err;
629 609
630 brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr); 610 brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
611 ifp->mac_addr);
631 ndev = ifp->ndev; 612 ndev = ifp->ndev;
632 613
633 /* set appropriate operations */ 614 /* set appropriate operations */
634 if (!ifp->idx) 615 ndev->netdev_ops = &brcmf_netdev_ops_pri;
635 ndev->netdev_ops = &brcmf_netdev_ops_pri;
636 else
637 ndev->netdev_ops = &brcmf_netdev_ops_virt;
638 616
639 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; 617 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
640 ndev->ethtool_ops = &brcmf_ethtool_ops; 618 ndev->ethtool_ops = &brcmf_ethtool_ops;
@@ -645,7 +623,14 @@ int brcmf_net_attach(struct brcmf_if *ifp)
645 /* set the mac address */ 623 /* set the mac address */
646 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); 624 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
647 625
648 if (register_netdev(ndev) != 0) { 626 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
627 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
628
629 if (rtnl_locked)
630 err = register_netdevice(ndev);
631 else
632 err = register_netdev(ndev);
633 if (err != 0) {
649 brcmf_err("couldn't register the net device\n"); 634 brcmf_err("couldn't register the net device\n");
650 goto fail; 635 goto fail;
651 } 636 }
@@ -659,16 +644,78 @@ fail:
659 return -EBADE; 644 return -EBADE;
660} 645}
661 646
662struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, 647static int brcmf_net_p2p_open(struct net_device *ndev)
663 char *name, u8 *addr_mask) 648{
649 brcmf_dbg(TRACE, "Enter\n");
650
651 return brcmf_cfg80211_up(ndev);
652}
653
654static int brcmf_net_p2p_stop(struct net_device *ndev)
655{
656 brcmf_dbg(TRACE, "Enter\n");
657
658 return brcmf_cfg80211_down(ndev);
659}
660
661static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
662 struct ifreq *ifr, int cmd)
663{
664 brcmf_dbg(TRACE, "Enter\n");
665 return 0;
666}
667
668static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
669 struct net_device *ndev)
670{
671 if (skb)
672 dev_kfree_skb_any(skb);
673
674 return NETDEV_TX_OK;
675}
676
677static const struct net_device_ops brcmf_netdev_ops_p2p = {
678 .ndo_open = brcmf_net_p2p_open,
679 .ndo_stop = brcmf_net_p2p_stop,
680 .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
681 .ndo_start_xmit = brcmf_net_p2p_start_xmit
682};
683
684static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
685{
686 struct net_device *ndev;
687
688 brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
689 ifp->mac_addr);
690 ndev = ifp->ndev;
691
692 ndev->netdev_ops = &brcmf_netdev_ops_p2p;
693
694 /* set the mac address */
695 memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
696
697 if (register_netdev(ndev) != 0) {
698 brcmf_err("couldn't register the p2p net device\n");
699 goto fail;
700 }
701
702 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
703
704 return 0;
705
706fail:
707 return -EBADE;
708}
709
710struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
711 char *name, u8 *mac_addr)
664{ 712{
665 struct brcmf_if *ifp; 713 struct brcmf_if *ifp;
666 struct net_device *ndev; 714 struct net_device *ndev;
667 int i;
668 715
669 brcmf_dbg(TRACE, "idx %d\n", ifidx); 716 brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifidx);
670 717
671 ifp = drvr->iflist[ifidx]; 718 ifp = drvr->iflist[bssidx];
672 /* 719 /*
673 * Delete the existing interface before overwriting it 720 * Delete the existing interface before overwriting it
674 * in case we missed the BRCMF_E_IF_DEL event. 721 * in case we missed the BRCMF_E_IF_DEL event.
@@ -680,7 +727,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
680 netif_stop_queue(ifp->ndev); 727 netif_stop_queue(ifp->ndev);
681 unregister_netdev(ifp->ndev); 728 unregister_netdev(ifp->ndev);
682 free_netdev(ifp->ndev); 729 free_netdev(ifp->ndev);
683 drvr->iflist[ifidx] = NULL; 730 drvr->iflist[bssidx] = NULL;
684 } else { 731 } else {
685 brcmf_err("ignore IF event\n"); 732 brcmf_err("ignore IF event\n");
686 return ERR_PTR(-EINVAL); 733 return ERR_PTR(-EINVAL);
@@ -697,16 +744,15 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
697 ifp = netdev_priv(ndev); 744 ifp = netdev_priv(ndev);
698 ifp->ndev = ndev; 745 ifp->ndev = ndev;
699 ifp->drvr = drvr; 746 ifp->drvr = drvr;
700 drvr->iflist[ifidx] = ifp; 747 drvr->iflist[bssidx] = ifp;
701 ifp->idx = ifidx; 748 ifp->ifidx = ifidx;
702 ifp->bssidx = bssidx; 749 ifp->bssidx = bssidx;
703 750
704 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
705 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
706 751
707 if (addr_mask != NULL) 752 init_waitqueue_head(&ifp->pend_8021x_wait);
708 for (i = 0; i < ETH_ALEN; i++) 753
709 ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; 754 if (mac_addr != NULL)
755 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
710 756
711 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", 757 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
712 current->pid, ifp->ndev->name, ifp->mac_addr); 758 current->pid, ifp->ndev->name, ifp->mac_addr);
@@ -714,19 +760,18 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
714 return ifp; 760 return ifp;
715} 761}
716 762
717void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) 763void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
718{ 764{
719 struct brcmf_if *ifp; 765 struct brcmf_if *ifp;
720 766
721 brcmf_dbg(TRACE, "idx %d\n", ifidx); 767 ifp = drvr->iflist[bssidx];
722
723 ifp = drvr->iflist[ifidx];
724 if (!ifp) { 768 if (!ifp) {
725 brcmf_err("Null interface\n"); 769 brcmf_err("Null interface, idx=%d\n", bssidx);
726 return; 770 return;
727 } 771 }
772 brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
728 if (ifp->ndev) { 773 if (ifp->ndev) {
729 if (ifidx == 0) { 774 if (bssidx == 0) {
730 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { 775 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
731 rtnl_lock(); 776 rtnl_lock();
732 brcmf_netdev_stop(ifp->ndev); 777 brcmf_netdev_stop(ifp->ndev);
@@ -736,12 +781,14 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
736 netif_stop_queue(ifp->ndev); 781 netif_stop_queue(ifp->ndev);
737 } 782 }
738 783
739 cancel_work_sync(&ifp->setmacaddr_work); 784 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
740 cancel_work_sync(&ifp->multicast_work); 785 cancel_work_sync(&ifp->setmacaddr_work);
786 cancel_work_sync(&ifp->multicast_work);
787 }
741 788
742 unregister_netdev(ifp->ndev); 789 unregister_netdev(ifp->ndev);
743 drvr->iflist[ifidx] = NULL; 790 drvr->iflist[bssidx] = NULL;
744 if (ifidx == 0) 791 if (bssidx == 0)
745 brcmf_cfg80211_detach(drvr->config); 792 brcmf_cfg80211_detach(drvr->config);
746 free_netdev(ifp->ndev); 793 free_netdev(ifp->ndev);
747 } 794 }
@@ -781,8 +828,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
781 828
782 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); 829 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
783 830
784 init_waitqueue_head(&drvr->pend_8021x_wait);
785
786 return ret; 831 return ret;
787 832
788fail: 833fail:
@@ -797,6 +842,7 @@ int brcmf_bus_start(struct device *dev)
797 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 842 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
798 struct brcmf_pub *drvr = bus_if->drvr; 843 struct brcmf_pub *drvr = bus_if->drvr;
799 struct brcmf_if *ifp; 844 struct brcmf_if *ifp;
845 struct brcmf_if *p2p_ifp;
800 846
801 brcmf_dbg(TRACE, "\n"); 847 brcmf_dbg(TRACE, "\n");
802 848
@@ -812,6 +858,13 @@ int brcmf_bus_start(struct device *dev)
812 if (IS_ERR(ifp)) 858 if (IS_ERR(ifp))
813 return PTR_ERR(ifp); 859 return PTR_ERR(ifp);
814 860
861 if (brcmf_p2p_enable)
862 p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
863 else
864 p2p_ifp = NULL;
865 if (IS_ERR(p2p_ifp))
866 p2p_ifp = NULL;
867
815 /* signal bus ready */ 868 /* signal bus ready */
816 bus_if->state = BRCMF_BUS_DATA; 869 bus_if->state = BRCMF_BUS_DATA;
817 870
@@ -830,16 +883,22 @@ int brcmf_bus_start(struct device *dev)
830 if (ret < 0) 883 if (ret < 0)
831 goto fail; 884 goto fail;
832 885
833 ret = brcmf_net_attach(ifp); 886 ret = brcmf_net_attach(ifp, false);
834fail: 887fail:
835 if (ret < 0) { 888 if (ret < 0) {
836 brcmf_err("failed: %d\n", ret); 889 brcmf_err("failed: %d\n", ret);
837 if (drvr->config) 890 if (drvr->config)
838 brcmf_cfg80211_detach(drvr->config); 891 brcmf_cfg80211_detach(drvr->config);
839 free_netdev(drvr->iflist[0]->ndev); 892 free_netdev(ifp->ndev);
840 drvr->iflist[0] = NULL; 893 drvr->iflist[0] = NULL;
894 if (p2p_ifp) {
895 free_netdev(p2p_ifp->ndev);
896 drvr->iflist[1] = NULL;
897 }
841 return ret; 898 return ret;
842 } 899 }
900 if ((brcmf_p2p_enable) && (p2p_ifp))
901 brcmf_net_p2p_attach(p2p_ifp);
843 902
844 return 0; 903 return 0;
845} 904}
@@ -865,12 +924,13 @@ void brcmf_dev_reset(struct device *dev)
865 if (drvr == NULL) 924 if (drvr == NULL)
866 return; 925 return;
867 926
868 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1); 927 if (drvr->iflist[0])
928 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
869} 929}
870 930
871void brcmf_detach(struct device *dev) 931void brcmf_detach(struct device *dev)
872{ 932{
873 int i; 933 s32 i;
874 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 934 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
875 struct brcmf_pub *drvr = bus_if->drvr; 935 struct brcmf_pub *drvr = bus_if->drvr;
876 936
@@ -897,19 +957,18 @@ void brcmf_detach(struct device *dev)
897 kfree(drvr); 957 kfree(drvr);
898} 958}
899 959
900static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) 960static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
901{ 961{
902 return atomic_read(&drvr->pend_8021x_cnt); 962 return atomic_read(&ifp->pend_8021x_cnt);
903} 963}
904 964
905int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 965int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
906{ 966{
907 struct brcmf_if *ifp = netdev_priv(ndev); 967 struct brcmf_if *ifp = netdev_priv(ndev);
908 struct brcmf_pub *drvr = ifp->drvr;
909 int err; 968 int err;
910 969
911 err = wait_event_timeout(drvr->pend_8021x_wait, 970 err = wait_event_timeout(ifp->pend_8021x_wait,
912 !brcmf_get_pend_8021x_cnt(drvr), 971 !brcmf_get_pend_8021x_cnt(ifp),
913 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); 972 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
914 973
915 WARN_ON(!err); 974 WARN_ON(!err);
@@ -917,6 +976,16 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
917 return !err; 976 return !err;
918} 977}
919 978
979/*
980 * return chip id and rev of the device encoded in u32.
981 */
982u32 brcmf_get_chip_info(struct brcmf_if *ifp)
983{
984 struct brcmf_bus *bus = ifp->drvr->bus_if;
985
986 return bus->chip << 4 | bus->chiprev;
987}
988
920static void brcmf_driver_init(struct work_struct *work) 989static void brcmf_driver_init(struct work_struct *work)
921{ 990{
922 brcmf_debugfs_init(); 991 brcmf_debugfs_init();
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 6d786a281f1e..4469321c0eb3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1096,7 +1096,6 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1096 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && 1096 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
1097 type != BRCMF_SDIO_FT_SUPER) { 1097 type != BRCMF_SDIO_FT_SUPER) {
1098 brcmf_err("HW header length too long\n"); 1098 brcmf_err("HW header length too long\n");
1099 bus->sdiodev->bus_if->dstats.rx_errors++;
1100 bus->sdcnt.rx_toolong++; 1099 bus->sdcnt.rx_toolong++;
1101 brcmf_sdbrcm_rxfail(bus, false, false); 1100 brcmf_sdbrcm_rxfail(bus, false, false);
1102 rd->len = 0; 1101 rd->len = 0;
@@ -1298,7 +1297,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1298 if (errcode < 0) { 1297 if (errcode < 0) {
1299 brcmf_err("glom read of %d bytes failed: %d\n", 1298 brcmf_err("glom read of %d bytes failed: %d\n",
1300 dlen, errcode); 1299 dlen, errcode);
1301 bus->sdiodev->bus_if->dstats.rx_errors++;
1302 1300
1303 sdio_claim_host(bus->sdiodev->func[1]); 1301 sdio_claim_host(bus->sdiodev->func[1]);
1304 if (bus->glomerr++ < 3) { 1302 if (bus->glomerr++ < 3) {
@@ -1477,7 +1475,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1477 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { 1475 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
1478 brcmf_err("%d-byte control read exceeds %d-byte buffer\n", 1476 brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
1479 rdlen, bus->sdiodev->bus_if->maxctl); 1477 rdlen, bus->sdiodev->bus_if->maxctl);
1480 bus->sdiodev->bus_if->dstats.rx_errors++;
1481 brcmf_sdbrcm_rxfail(bus, false, false); 1478 brcmf_sdbrcm_rxfail(bus, false, false);
1482 goto done; 1479 goto done;
1483 } 1480 }
@@ -1485,7 +1482,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1485 if ((len - doff) > bus->sdiodev->bus_if->maxctl) { 1482 if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
1486 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", 1483 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1487 len, len - doff, bus->sdiodev->bus_if->maxctl); 1484 len, len - doff, bus->sdiodev->bus_if->maxctl);
1488 bus->sdiodev->bus_if->dstats.rx_errors++;
1489 bus->sdcnt.rx_toolong++; 1485 bus->sdcnt.rx_toolong++;
1490 brcmf_sdbrcm_rxfail(bus, false, false); 1486 brcmf_sdbrcm_rxfail(bus, false, false);
1491 goto done; 1487 goto done;
@@ -1633,7 +1629,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1633 if (!pkt) { 1629 if (!pkt) {
1634 /* Give up on data, request rtx of events */ 1630 /* Give up on data, request rtx of events */
1635 brcmf_err("brcmu_pkt_buf_get_skb failed\n"); 1631 brcmf_err("brcmu_pkt_buf_get_skb failed\n");
1636 bus->sdiodev->bus_if->dstats.rx_dropped++;
1637 brcmf_sdbrcm_rxfail(bus, false, 1632 brcmf_sdbrcm_rxfail(bus, false,
1638 RETRYCHAN(rd->channel)); 1633 RETRYCHAN(rd->channel));
1639 sdio_release_host(bus->sdiodev->func[1]); 1634 sdio_release_host(bus->sdiodev->func[1]);
@@ -1651,7 +1646,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1651 brcmf_err("read %d bytes from channel %d failed: %d\n", 1646 brcmf_err("read %d bytes from channel %d failed: %d\n",
1652 rd->len, rd->channel, sdret); 1647 rd->len, rd->channel, sdret);
1653 brcmu_pkt_buf_free_skb(pkt); 1648 brcmu_pkt_buf_free_skb(pkt);
1654 bus->sdiodev->bus_if->dstats.rx_errors++;
1655 sdio_claim_host(bus->sdiodev->func[1]); 1649 sdio_claim_host(bus->sdiodev->func[1]);
1656 brcmf_sdbrcm_rxfail(bus, true, 1650 brcmf_sdbrcm_rxfail(bus, true,
1657 RETRYCHAN(rd->channel)); 1651 RETRYCHAN(rd->channel));
@@ -1939,10 +1933,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1939 datalen = pkt->len - SDPCM_HDRLEN; 1933 datalen = pkt->len - SDPCM_HDRLEN;
1940 1934
1941 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); 1935 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1942 if (ret)
1943 bus->sdiodev->bus_if->dstats.tx_errors++;
1944 else
1945 bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
1946 1936
1947 /* In poll mode, need to check for other events */ 1937 /* In poll mode, need to check for other events */
1948 if (!bus->intr && cnt) { 1938 if (!bus->intr && cnt) {
@@ -1961,8 +1951,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1961 } 1951 }
1962 1952
1963 /* Deflow-control stack if needed */ 1953 /* Deflow-control stack if needed */
1964 if (bus->sdiodev->bus_if->drvr_up && 1954 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
1965 (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
1966 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 1955 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
1967 bus->txoff = false; 1956 bus->txoff = false;
1968 brcmf_txflowblock(bus->sdiodev->dev, false); 1957 brcmf_txflowblock(bus->sdiodev->dev, false);
@@ -2709,9 +2698,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2709 * address of sdpcm_shared structure 2698 * address of sdpcm_shared structure
2710 */ 2699 */
2711 sdio_claim_host(bus->sdiodev->func[1]); 2700 sdio_claim_host(bus->sdiodev->func[1]);
2701 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2712 rv = brcmf_sdbrcm_membytes(bus, false, shaddr, 2702 rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
2713 (u8 *)&addr_le, 4); 2703 (u8 *)&addr_le, 4);
2714 sdio_claim_host(bus->sdiodev->func[1]); 2704 sdio_release_host(bus->sdiodev->func[1]);
2715 if (rv < 0) 2705 if (rv < 0)
2716 return rv; 2706 return rv;
2717 2707
@@ -2730,10 +2720,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2730 } 2720 }
2731 2721
2732 /* Read hndrte_shared structure */ 2722 /* Read hndrte_shared structure */
2733 sdio_claim_host(bus->sdiodev->func[1]);
2734 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, 2723 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
2735 sizeof(struct sdpcm_shared_le)); 2724 sizeof(struct sdpcm_shared_le));
2736 sdio_release_host(bus->sdiodev->func[1]);
2737 if (rv < 0) 2725 if (rv < 0)
2738 return rv; 2726 return rv;
2739 2727
@@ -2835,14 +2823,12 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2835 if ((sh->flags & SDPCM_SHARED_TRAP) == 0) 2823 if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
2836 return 0; 2824 return 0;
2837 2825
2838 sdio_claim_host(bus->sdiodev->func[1]);
2839 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, 2826 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
2840 sizeof(struct brcmf_trap_info)); 2827 sizeof(struct brcmf_trap_info));
2841 if (error < 0) 2828 if (error < 0)
2842 return error; 2829 return error;
2843 2830
2844 nbytes = brcmf_sdio_dump_console(bus, sh, data, count); 2831 nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
2845 sdio_release_host(bus->sdiodev->func[1]);
2846 if (nbytes < 0) 2832 if (nbytes < 0)
2847 return nbytes; 2833 return nbytes;
2848 2834
@@ -3307,9 +3293,6 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
3307{ 3293{
3308 int ret; 3294 int ret;
3309 3295
3310 if (bus->sdiodev->bus_if->drvr_up)
3311 return -EISCONN;
3312
3313 ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, 3296 ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
3314 &bus->sdiodev->func[2]->dev); 3297 &bus->sdiodev->func[2]->dev);
3315 if (ret) { 3298 if (ret) {
@@ -3940,6 +3923,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3940 /* Assign bus interface call back */ 3923 /* Assign bus interface call back */
3941 bus->sdiodev->bus_if->dev = bus->sdiodev->dev; 3924 bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
3942 bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; 3925 bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops;
3926 bus->sdiodev->bus_if->chip = bus->ci->chip;
3927 bus->sdiodev->bus_if->chiprev = bus->ci->chiprev;
3943 3928
3944 /* Attach to the brcmf/OS/network interface */ 3929 /* Attach to the brcmf/OS/network interface */
3945 ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev); 3930 ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index ba0b22512f12..e9d6f91a1f2b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -189,24 +189,24 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
189 return; 189 return;
190 } 190 }
191 191
192 ifp = drvr->iflist[ifevent->ifidx]; 192 ifp = drvr->iflist[ifevent->bssidx];
193 193
194 if (ifevent->action == BRCMF_E_IF_ADD) { 194 if (ifevent->action == BRCMF_E_IF_ADD) {
195 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, 195 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
196 emsg->addr); 196 emsg->addr);
197 ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx, 197 ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx,
198 emsg->ifname, emsg->addr); 198 emsg->ifname, emsg->addr);
199 if (IS_ERR(ifp)) 199 if (IS_ERR(ifp))
200 return; 200 return;
201 201
202 if (!drvr->fweh.evt_handler[BRCMF_E_IF]) 202 if (!drvr->fweh.evt_handler[BRCMF_E_IF])
203 err = brcmf_net_attach(ifp); 203 err = brcmf_net_attach(ifp, false);
204 } 204 }
205 205
206 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); 206 err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
207 207
208 if (ifevent->action == BRCMF_E_IF_DEL) 208 if (ifevent->action == BRCMF_E_IF_DEL)
209 brcmf_del_if(drvr, ifevent->ifidx); 209 brcmf_del_if(drvr, ifevent->bssidx);
210} 210}
211 211
212/** 212/**
@@ -250,8 +250,6 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
250 drvr = container_of(fweh, struct brcmf_pub, fweh); 250 drvr = container_of(fweh, struct brcmf_pub, fweh);
251 251
252 while ((event = brcmf_fweh_dequeue_event(fweh))) { 252 while ((event = brcmf_fweh_dequeue_event(fweh))) {
253 ifp = drvr->iflist[event->ifidx];
254
255 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n", 253 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n",
256 brcmf_fweh_event_name(event->code), event->code, 254 brcmf_fweh_event_name(event->code), event->code,
257 event->emsg.ifidx, event->emsg.bsscfgidx, 255 event->emsg.ifidx, event->emsg.bsscfgidx,
@@ -283,6 +281,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
283 goto event_free; 281 goto event_free;
284 } 282 }
285 283
284 ifp = drvr->iflist[emsg.bsscfgidx];
286 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, 285 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg,
287 event->data); 286 event->data);
288 if (err) { 287 if (err) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 36901f76a3b5..8c39b51dcccf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -83,6 +83,7 @@ struct brcmf_event;
83 BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \ 83 BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \
84 BRCMF_ENUM_DEF(TRACE, 52) \ 84 BRCMF_ENUM_DEF(TRACE, 52) \
85 BRCMF_ENUM_DEF(IF, 54) \ 85 BRCMF_ENUM_DEF(IF, 54) \
86 BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
86 BRCMF_ENUM_DEF(RSSI, 56) \ 87 BRCMF_ENUM_DEF(RSSI, 56) \
87 BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \ 88 BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \
88 BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \ 89 BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
@@ -96,8 +97,11 @@ struct brcmf_event;
96 BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \ 97 BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \
97 BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \ 98 BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \
98 BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \ 99 BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \
100 BRCMF_ENUM_DEF(PROBERESP_MSG, 71) \
101 BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
99 BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ 102 BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
100 BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) 103 BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
104 BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75)
101 105
102#define BRCMF_ENUM_DEF(id, val) \ 106#define BRCMF_ENUM_DEF(id, val) \
103 BRCMF_E_##id = (val), 107 BRCMF_E_##id = (val),
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index d8d8b6549dc5..8d1def935b8d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -45,9 +45,10 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
45 if (data != NULL) 45 if (data != NULL)
46 len = min_t(uint, len, BRCMF_DCMD_MAXLEN); 46 len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
47 if (set) 47 if (set)
48 err = brcmf_proto_cdc_set_dcmd(drvr, ifp->idx, cmd, data, len); 48 err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data,
49 len);
49 else 50 else
50 err = brcmf_proto_cdc_query_dcmd(drvr, ifp->idx, cmd, data, 51 err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data,
51 len); 52 len);
52 53
53 if (err >= 0) 54 if (err >= 0)
@@ -100,6 +101,7 @@ brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data)
100 __le32 data_le = cpu_to_le32(data); 101 __le32 data_le = cpu_to_le32(data);
101 102
102 mutex_lock(&ifp->drvr->proto_block); 103 mutex_lock(&ifp->drvr->proto_block);
104 brcmf_dbg(FIL, "cmd=%d, value=%d\n", cmd, data);
103 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true); 105 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true);
104 mutex_unlock(&ifp->drvr->proto_block); 106 mutex_unlock(&ifp->drvr->proto_block);
105 107
@@ -116,6 +118,7 @@ brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data)
116 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false); 118 err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false);
117 mutex_unlock(&ifp->drvr->proto_block); 119 mutex_unlock(&ifp->drvr->proto_block);
118 *data = le32_to_cpu(data_le); 120 *data = le32_to_cpu(data_le);
121 brcmf_dbg(FIL, "cmd=%d, value=%d\n", cmd, *data);
119 122
120 return err; 123 return err;
121} 124}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
new file mode 100644
index 000000000000..0f2c83bc95dc
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2012 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
18#ifndef FWIL_TYPES_H_
19#define FWIL_TYPES_H_
20
21#include <linux/if_ether.h>
22
23
24#define BRCMF_FIL_ACTION_FRAME_SIZE 1800
25
26
27enum brcmf_fil_p2p_if_types {
28 BRCMF_FIL_P2P_IF_CLIENT,
29 BRCMF_FIL_P2P_IF_GO,
30 BRCMF_FIL_P2P_IF_DYNBCN_GO,
31 BRCMF_FIL_P2P_IF_DEV,
32};
33
34struct brcmf_fil_p2p_if_le {
35 u8 addr[ETH_ALEN];
36 __le16 type;
37 __le16 chspec;
38};
39
40struct brcmf_fil_chan_info_le {
41 __le32 hw_channel;
42 __le32 target_channel;
43 __le32 scan_channel;
44};
45
46struct brcmf_fil_action_frame_le {
47 u8 da[ETH_ALEN];
48 __le16 len;
49 __le32 packet_id;
50 u8 data[BRCMF_FIL_ACTION_FRAME_SIZE];
51};
52
53struct brcmf_fil_af_params_le {
54 __le32 channel;
55 __le32 dwell_time;
56 u8 bssid[ETH_ALEN];
57 u8 pad[2];
58 struct brcmf_fil_action_frame_le action_frame;
59};
60
61struct brcmf_fil_bss_enable_le {
62 __le32 bsscfg_idx;
63 __le32 enable;
64};
65
66#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
new file mode 100644
index 000000000000..4166e642068b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -0,0 +1,2277 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/slab.h>
17#include <linux/netdevice.h>
18#include <net/cfg80211.h>
19
20#include <brcmu_wifi.h>
21#include <brcmu_utils.h>
22#include <defs.h>
23#include <dhd.h>
24#include <dhd_dbg.h>
25#include "fwil.h"
26#include "fwil_types.h"
27#include "p2p.h"
28#include "wl_cfg80211.h"
29
30/* parameters used for p2p escan */
31#define P2PAPI_SCAN_NPROBES 1
32#define P2PAPI_SCAN_DWELL_TIME_MS 80
33#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
34#define P2PAPI_SCAN_HOME_TIME_MS 60
35#define P2PAPI_SCAN_NPROBS_TIME_MS 30
36#define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS 100
37#define WL_SCAN_CONNECT_DWELL_TIME_MS 200
38#define WL_SCAN_JOIN_PROBE_INTERVAL_MS 20
39
40#define BRCMF_P2P_WILDCARD_SSID "DIRECT-"
41#define BRCMF_P2P_WILDCARD_SSID_LEN (sizeof(BRCMF_P2P_WILDCARD_SSID) - 1)
42
43#define SOCIAL_CHAN_1 1
44#define SOCIAL_CHAN_2 6
45#define SOCIAL_CHAN_3 11
46#define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
47 (channel == SOCIAL_CHAN_2) || \
48 (channel == SOCIAL_CHAN_3))
49#define SOCIAL_CHAN_CNT 3
50#define AF_PEER_SEARCH_CNT 2
51
52#define BRCMF_SCB_TIMEOUT_VALUE 20
53
54#define P2P_VER 9 /* P2P version: 9=WiFi P2P v1.0 */
55#define P2P_PUB_AF_CATEGORY 0x04
56#define P2P_PUB_AF_ACTION 0x09
57#define P2P_AF_CATEGORY 0x7f
58#define P2P_OUI "\x50\x6F\x9A" /* P2P OUI */
59#define P2P_OUI_LEN 3 /* P2P OUI length */
60
61/* Action Frame Constants */
62#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action */
63#define DOT11_ACTION_CAT_OFF 0 /* category offset */
64#define DOT11_ACTION_ACT_OFF 1 /* action offset */
65
66#define P2P_AF_DWELL_TIME 200
67#define P2P_AF_MIN_DWELL_TIME 100
68#define P2P_AF_MED_DWELL_TIME 400
69#define P2P_AF_LONG_DWELL_TIME 1000
70#define P2P_AF_TX_MAX_RETRY 1
71#define P2P_AF_MAX_WAIT_TIME 2000
72#define P2P_INVALID_CHANNEL -1
73#define P2P_CHANNEL_SYNC_RETRY 5
74#define P2P_AF_FRM_SCAN_MAX_WAIT 1500
75#define P2P_DEFAULT_SLEEP_TIME_VSDB 200
76
77/* WiFi P2P Public Action Frame OUI Subtypes */
78#define P2P_PAF_GON_REQ 0 /* Group Owner Negotiation Req */
79#define P2P_PAF_GON_RSP 1 /* Group Owner Negotiation Rsp */
80#define P2P_PAF_GON_CONF 2 /* Group Owner Negotiation Confirm */
81#define P2P_PAF_INVITE_REQ 3 /* P2P Invitation Request */
82#define P2P_PAF_INVITE_RSP 4 /* P2P Invitation Response */
83#define P2P_PAF_DEVDIS_REQ 5 /* Device Discoverability Request */
84#define P2P_PAF_DEVDIS_RSP 6 /* Device Discoverability Response */
85#define P2P_PAF_PROVDIS_REQ 7 /* Provision Discovery Request */
86#define P2P_PAF_PROVDIS_RSP 8 /* Provision Discovery Response */
87#define P2P_PAF_SUBTYPE_INVALID 255 /* Invalid Subtype */
88
89/* WiFi P2P Action Frame OUI Subtypes */
90#define P2P_AF_NOTICE_OF_ABSENCE 0 /* Notice of Absence */
91#define P2P_AF_PRESENCE_REQ 1 /* P2P Presence Request */
92#define P2P_AF_PRESENCE_RSP 2 /* P2P Presence Response */
93#define P2P_AF_GO_DISC_REQ 3 /* GO Discoverability Request */
94
95/* P2P Service Discovery related */
96#define P2PSD_ACTION_CATEGORY 0x04 /* Public action frame */
97#define P2PSD_ACTION_ID_GAS_IREQ 0x0a /* GAS Initial Request AF */
98#define P2PSD_ACTION_ID_GAS_IRESP 0x0b /* GAS Initial Response AF */
99#define P2PSD_ACTION_ID_GAS_CREQ 0x0c /* GAS Comback Request AF */
100#define P2PSD_ACTION_ID_GAS_CRESP 0x0d /* GAS Comback Response AF */
101
102/**
103 * struct brcmf_p2p_disc_st_le - set discovery state in firmware.
104 *
105 * @state: requested discovery state (see enum brcmf_p2p_disc_state).
106 * @chspec: channel parameter for %WL_P2P_DISC_ST_LISTEN state.
107 * @dwell: dwell time in ms for %WL_P2P_DISC_ST_LISTEN state.
108 */
109struct brcmf_p2p_disc_st_le {
110 u8 state;
111 __le16 chspec;
112 __le16 dwell;
113};
114
115/**
116 * enum brcmf_p2p_disc_state - P2P discovery state values
117 *
118 * @WL_P2P_DISC_ST_SCAN: P2P discovery with wildcard SSID and P2P IE.
119 * @WL_P2P_DISC_ST_LISTEN: P2P discovery off-channel for specified time.
120 * @WL_P2P_DISC_ST_SEARCH: P2P discovery with P2P wildcard SSID and P2P IE.
121 */
122enum brcmf_p2p_disc_state {
123 WL_P2P_DISC_ST_SCAN,
124 WL_P2P_DISC_ST_LISTEN,
125 WL_P2P_DISC_ST_SEARCH
126};
127
128/**
129 * struct brcmf_p2p_scan_le - P2P specific scan request.
130 *
131 * @type: type of scan method requested (values: 'E' or 'S').
132 * @reserved: reserved (ignored).
133 * @eparams: parameters used for type 'E'.
134 * @sparams: parameters used for type 'S'.
135 */
136struct brcmf_p2p_scan_le {
137 u8 type;
138 u8 reserved[3];
139 union {
140 struct brcmf_escan_params_le eparams;
141 struct brcmf_scan_params_le sparams;
142 };
143};
144
145/**
146 * struct brcmf_p2p_pub_act_frame - WiFi P2P Public Action Frame
147 *
148 * @category: P2P_PUB_AF_CATEGORY
149 * @action: P2P_PUB_AF_ACTION
150 * @oui[3]: P2P_OUI
151 * @oui_type: OUI type - P2P_VER
152 * @subtype: OUI subtype - P2P_TYPE_*
153 * @dialog_token: nonzero, identifies req/rsp transaction
154 * @elts[1]: Variable length information elements.
155 */
156struct brcmf_p2p_pub_act_frame {
157 u8 category;
158 u8 action;
159 u8 oui[3];
160 u8 oui_type;
161 u8 subtype;
162 u8 dialog_token;
163 u8 elts[1];
164};
165
166/**
167 * struct brcmf_p2p_action_frame - WiFi P2P Action Frame
168 *
169 * @category: P2P_AF_CATEGORY
170 * @OUI[3]: OUI - P2P_OUI
171 * @type: OUI Type - P2P_VER
172 * @subtype: OUI Subtype - P2P_AF_*
173 * @dialog_token: nonzero, identifies req/resp tranaction
174 * @elts[1]: Variable length information elements.
175 */
176struct brcmf_p2p_action_frame {
177 u8 category;
178 u8 oui[3];
179 u8 type;
180 u8 subtype;
181 u8 dialog_token;
182 u8 elts[1];
183};
184
185/**
186 * struct brcmf_p2psd_gas_pub_act_frame - Wi-Fi GAS Public Action Frame
187 *
188 * @category: 0x04 Public Action Frame
189 * @action: 0x6c Advertisement Protocol
190 * @dialog_token: nonzero, identifies req/rsp transaction
191 * @query_data[1]: Query Data. SD gas ireq SD gas iresp
192 */
193struct brcmf_p2psd_gas_pub_act_frame {
194 u8 category;
195 u8 action;
196 u8 dialog_token;
197 u8 query_data[1];
198};
199
200/**
201 * struct brcmf_config_af_params - Action Frame Parameters for tx.
202 *
203 * @mpc_onoff: To make sure to send successfully action frame, we have to
204 * turn off mpc 0: off, 1: on, (-1): do nothing
205 * @search_channel: 1: search peer's channel to send af
206 * extra_listen: keep the dwell time to get af response frame.
207 */
208struct brcmf_config_af_params {
209 s32 mpc_onoff;
210 bool search_channel;
211 bool extra_listen;
212};
213
214/**
215 * brcmf_p2p_is_pub_action() - true if p2p public type frame.
216 *
217 * @frame: action frame data.
218 * @frame_len: length of action frame data.
219 *
220 * Determine if action frame is p2p public action type
221 */
222static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len)
223{
224 struct brcmf_p2p_pub_act_frame *pact_frm;
225
226 if (frame == NULL)
227 return false;
228
229 pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
230 if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1)
231 return false;
232
233 if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
234 pact_frm->action == P2P_PUB_AF_ACTION &&
235 pact_frm->oui_type == P2P_VER &&
236 memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
237 return true;
238
239 return false;
240}
241
242/**
243 * brcmf_p2p_is_p2p_action() - true if p2p action type frame.
244 *
245 * @frame: action frame data.
246 * @frame_len: length of action frame data.
247 *
248 * Determine if action frame is p2p action type
249 */
250static bool brcmf_p2p_is_p2p_action(void *frame, u32 frame_len)
251{
252 struct brcmf_p2p_action_frame *act_frm;
253
254 if (frame == NULL)
255 return false;
256
257 act_frm = (struct brcmf_p2p_action_frame *)frame;
258 if (frame_len < sizeof(struct brcmf_p2p_action_frame) - 1)
259 return false;
260
261 if (act_frm->category == P2P_AF_CATEGORY &&
262 act_frm->type == P2P_VER &&
263 memcmp(act_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
264 return true;
265
266 return false;
267}
268
269/**
270 * brcmf_p2p_is_gas_action() - true if p2p gas action type frame.
271 *
272 * @frame: action frame data.
273 * @frame_len: length of action frame data.
274 *
275 * Determine if action frame is p2p gas action type
276 */
277static bool brcmf_p2p_is_gas_action(void *frame, u32 frame_len)
278{
279 struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm;
280
281 if (frame == NULL)
282 return false;
283
284 sd_act_frm = (struct brcmf_p2psd_gas_pub_act_frame *)frame;
285 if (frame_len < sizeof(struct brcmf_p2psd_gas_pub_act_frame) - 1)
286 return false;
287
288 if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
289 return false;
290
291 if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
292 sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP ||
293 sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ ||
294 sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
295 return true;
296
297 return false;
298}
299
300/**
301 * brcmf_p2p_print_actframe() - debug print routine.
302 *
303 * @tx: Received or to be transmitted
304 * @frame: action frame data.
305 * @frame_len: length of action frame data.
306 *
307 * Print information about the p2p action frame
308 */
309
310#ifdef DEBUG
311
312static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len)
313{
314 struct brcmf_p2p_pub_act_frame *pact_frm;
315 struct brcmf_p2p_action_frame *act_frm;
316 struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm;
317
318 if (!frame || frame_len <= 2)
319 return;
320
321 if (brcmf_p2p_is_pub_action(frame, frame_len)) {
322 pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
323 switch (pact_frm->subtype) {
324 case P2P_PAF_GON_REQ:
325 brcmf_dbg(TRACE, "%s P2P Group Owner Negotiation Req Frame\n",
326 (tx) ? "TX" : "RX");
327 break;
328 case P2P_PAF_GON_RSP:
329 brcmf_dbg(TRACE, "%s P2P Group Owner Negotiation Rsp Frame\n",
330 (tx) ? "TX" : "RX");
331 break;
332 case P2P_PAF_GON_CONF:
333 brcmf_dbg(TRACE, "%s P2P Group Owner Negotiation Confirm Frame\n",
334 (tx) ? "TX" : "RX");
335 break;
336 case P2P_PAF_INVITE_REQ:
337 brcmf_dbg(TRACE, "%s P2P Invitation Request Frame\n",
338 (tx) ? "TX" : "RX");
339 break;
340 case P2P_PAF_INVITE_RSP:
341 brcmf_dbg(TRACE, "%s P2P Invitation Response Frame\n",
342 (tx) ? "TX" : "RX");
343 break;
344 case P2P_PAF_DEVDIS_REQ:
345 brcmf_dbg(TRACE, "%s P2P Device Discoverability Request Frame\n",
346 (tx) ? "TX" : "RX");
347 break;
348 case P2P_PAF_DEVDIS_RSP:
349 brcmf_dbg(TRACE, "%s P2P Device Discoverability Response Frame\n",
350 (tx) ? "TX" : "RX");
351 break;
352 case P2P_PAF_PROVDIS_REQ:
353 brcmf_dbg(TRACE, "%s P2P Provision Discovery Request Frame\n",
354 (tx) ? "TX" : "RX");
355 break;
356 case P2P_PAF_PROVDIS_RSP:
357 brcmf_dbg(TRACE, "%s P2P Provision Discovery Response Frame\n",
358 (tx) ? "TX" : "RX");
359 break;
360 default:
361 brcmf_dbg(TRACE, "%s Unknown P2P Public Action Frame\n",
362 (tx) ? "TX" : "RX");
363 break;
364 }
365 } else if (brcmf_p2p_is_p2p_action(frame, frame_len)) {
366 act_frm = (struct brcmf_p2p_action_frame *)frame;
367 switch (act_frm->subtype) {
368 case P2P_AF_NOTICE_OF_ABSENCE:
369 brcmf_dbg(TRACE, "%s P2P Notice of Absence Frame\n",
370 (tx) ? "TX" : "RX");
371 break;
372 case P2P_AF_PRESENCE_REQ:
373 brcmf_dbg(TRACE, "%s P2P Presence Request Frame\n",
374 (tx) ? "TX" : "RX");
375 break;
376 case P2P_AF_PRESENCE_RSP:
377 brcmf_dbg(TRACE, "%s P2P Presence Response Frame\n",
378 (tx) ? "TX" : "RX");
379 break;
380 case P2P_AF_GO_DISC_REQ:
381 brcmf_dbg(TRACE, "%s P2P Discoverability Request Frame\n",
382 (tx) ? "TX" : "RX");
383 break;
384 default:
385 brcmf_dbg(TRACE, "%s Unknown P2P Action Frame\n",
386 (tx) ? "TX" : "RX");
387 }
388
389 } else if (brcmf_p2p_is_gas_action(frame, frame_len)) {
390 sd_act_frm = (struct brcmf_p2psd_gas_pub_act_frame *)frame;
391 switch (sd_act_frm->action) {
392 case P2PSD_ACTION_ID_GAS_IREQ:
393 brcmf_dbg(TRACE, "%s P2P GAS Initial Request\n",
394 (tx) ? "TX" : "RX");
395 break;
396 case P2PSD_ACTION_ID_GAS_IRESP:
397 brcmf_dbg(TRACE, "%s P2P GAS Initial Response\n",
398 (tx) ? "TX" : "RX");
399 break;
400 case P2PSD_ACTION_ID_GAS_CREQ:
401 brcmf_dbg(TRACE, "%s P2P GAS Comback Request\n",
402 (tx) ? "TX" : "RX");
403 break;
404 case P2PSD_ACTION_ID_GAS_CRESP:
405 brcmf_dbg(TRACE, "%s P2P GAS Comback Response\n",
406 (tx) ? "TX" : "RX");
407 break;
408 default:
409 brcmf_dbg(TRACE, "%s Unknown P2P GAS Frame\n",
410 (tx) ? "TX" : "RX");
411 break;
412 }
413 }
414}
415
416#else
417
418static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len)
419{
420}
421
422#endif
423
424
425/**
426 * brcmf_p2p_chnr_to_chspec() - convert channel number to chanspec.
427 *
428 * @channel: channel number
429 */
430static u16 brcmf_p2p_chnr_to_chspec(u16 channel)
431{
432 u16 chanspec;
433
434 chanspec = channel & WL_CHANSPEC_CHAN_MASK;
435
436 if (channel <= CH_MAX_2G_CHANNEL)
437 chanspec |= WL_CHANSPEC_BAND_2G;
438 else
439 chanspec |= WL_CHANSPEC_BAND_5G;
440
441 chanspec |= WL_CHANSPEC_BW_20;
442 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
443
444 return chanspec;
445}
446
447
448/**
449 * brcmf_p2p_set_firmware() - prepare firmware for peer-to-peer operation.
450 *
451 * @ifp: ifp to use for iovars (primary).
452 * @p2p_mac: mac address to configure for p2p_da_override
453 */
454static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
455{
456 s32 ret = 0;
457
458 brcmf_fil_iovar_int_set(ifp, "apsta", 1);
459
460 /* In case of COB type, firmware has default mac address
461 * After Initializing firmware, we have to set current mac address to
462 * firmware for P2P device address
463 */
464 ret = brcmf_fil_iovar_data_set(ifp, "p2p_da_override", p2p_mac,
465 ETH_ALEN);
466 if (ret)
467 brcmf_err("failed to update device address ret %d\n", ret);
468
469 return ret;
470}
471
472/**
473 * brcmf_p2p_generate_bss_mac() - derive mac addresses for P2P.
474 *
475 * @p2p: P2P specific data.
476 *
477 * P2P needs mac addresses for P2P device and interface. These are
478 * derived from the primary net device, ie. the permanent ethernet
479 * address of the device.
480 */
481static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p)
482{
483 struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
484 struct brcmf_if *p2p_ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
485
486 /* Generate the P2P Device Address. This consists of the device's
487 * primary MAC address with the locally administered bit set.
488 */
489 memcpy(p2p->dev_addr, pri_ifp->mac_addr, ETH_ALEN);
490 p2p->dev_addr[0] |= 0x02;
491 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
492
493 /* Generate the P2P Interface Address. If the discovery and connection
494 * BSSCFGs need to simultaneously co-exist, then this address must be
495 * different from the P2P Device Address, but also locally administered.
496 */
497 memcpy(p2p->int_addr, p2p->dev_addr, ETH_ALEN);
498 p2p->int_addr[4] ^= 0x80;
499}
500
501/**
502 * brcmf_p2p_scan_is_p2p_request() - is cfg80211 scan request a P2P scan.
503 *
504 * @request: the scan request as received from cfg80211.
505 *
506 * returns true if one of the ssids in the request matches the
507 * P2P wildcard ssid; otherwise returns false.
508 */
509static bool brcmf_p2p_scan_is_p2p_request(struct cfg80211_scan_request *request)
510{
511 struct cfg80211_ssid *ssids = request->ssids;
512 int i;
513
514 for (i = 0; i < request->n_ssids; i++) {
515 if (ssids[i].ssid_len != BRCMF_P2P_WILDCARD_SSID_LEN)
516 continue;
517
518 brcmf_dbg(INFO, "comparing ssid \"%s\"", ssids[i].ssid);
519 if (!memcmp(BRCMF_P2P_WILDCARD_SSID, ssids[i].ssid,
520 BRCMF_P2P_WILDCARD_SSID_LEN))
521 return true;
522 }
523 return false;
524}
525
526/**
527 * brcmf_p2p_set_discover_state - set discover state in firmware.
528 *
529 * @ifp: low-level interface object.
530 * @state: discover state to set.
531 * @chanspec: channel parameters (for state @WL_P2P_DISC_ST_LISTEN only).
532 * @listen_ms: duration to listen (for state @WL_P2P_DISC_ST_LISTEN only).
533 */
534static s32 brcmf_p2p_set_discover_state(struct brcmf_if *ifp, u8 state,
535 u16 chanspec, u16 listen_ms)
536{
537 struct brcmf_p2p_disc_st_le discover_state;
538 s32 ret = 0;
539 brcmf_dbg(TRACE, "enter\n");
540
541 discover_state.state = state;
542 discover_state.chspec = cpu_to_le16(chanspec);
543 discover_state.dwell = cpu_to_le16(listen_ms);
544 ret = brcmf_fil_bsscfg_data_set(ifp, "p2p_state", &discover_state,
545 sizeof(discover_state));
546 return ret;
547}
548
549/**
550 * brcmf_p2p_deinit_discovery() - disable P2P device discovery.
551 *
552 * @p2p: P2P specific data.
553 *
554 * Resets the discovery state and disables it in firmware.
555 */
556static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p)
557{
558 struct brcmf_cfg80211_vif *vif;
559
560 brcmf_dbg(TRACE, "enter\n");
561
562 /* Set the discovery state to SCAN */
563 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
564 (void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
565
566 /* Disable P2P discovery in the firmware */
567 vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
568 (void)brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 0);
569
570 return 0;
571}
572
573/**
574 * brcmf_p2p_enable_discovery() - initialize and configure discovery.
575 *
576 * @p2p: P2P specific data.
577 *
578 * Initializes the discovery device and configure the virtual interface.
579 */
580static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p)
581{
582 struct brcmf_cfg80211_vif *vif;
583 s32 ret = 0;
584
585 brcmf_dbg(TRACE, "enter\n");
586 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
587 if (!vif) {
588 brcmf_err("P2P config device not available\n");
589 ret = -EPERM;
590 goto exit;
591 }
592
593 if (test_bit(BRCMF_P2P_STATUS_ENABLED, &p2p->status)) {
594 brcmf_dbg(INFO, "P2P config device already configured\n");
595 goto exit;
596 }
597
598 /* Re-initialize P2P Discovery in the firmware */
599 vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
600 ret = brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 1);
601 if (ret < 0) {
602 brcmf_err("set p2p_disc error\n");
603 goto exit;
604 }
605 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
606 ret = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
607 if (ret < 0) {
608 brcmf_err("unable to set WL_P2P_DISC_ST_SCAN\n");
609 goto exit;
610 }
611
612 /*
613 * Set wsec to any non-zero value in the discovery bsscfg
614 * to ensure our P2P probe responses have the privacy bit
615 * set in the 802.11 WPA IE. Some peer devices may not
616 * initiate WPS with us if this bit is not set.
617 */
618 ret = brcmf_fil_bsscfg_int_set(vif->ifp, "wsec", AES_ENABLED);
619 if (ret < 0) {
620 brcmf_err("wsec error %d\n", ret);
621 goto exit;
622 }
623
624 set_bit(BRCMF_P2P_STATUS_ENABLED, &p2p->status);
625exit:
626 return ret;
627}
628
629/**
630 * brcmf_p2p_escan() - initiate a P2P scan.
631 *
632 * @p2p: P2P specific data.
633 * @num_chans: number of channels to scan.
634 * @chanspecs: channel parameters for @num_chans channels.
635 * @search_state: P2P discover state to use.
636 * @action: scan action to pass to firmware.
637 * @bss_type: type of P2P bss.
638 */
639static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
640 u16 chanspecs[], s32 search_state, u16 action,
641 enum p2p_bss_type bss_type)
642{
643 s32 ret = 0;
644 s32 memsize = offsetof(struct brcmf_p2p_scan_le,
645 eparams.params_le.channel_list);
646 s32 nprobes;
647 s32 active;
648 u32 i;
649 u8 *memblk;
650 struct brcmf_cfg80211_vif *vif;
651 struct brcmf_p2p_scan_le *p2p_params;
652 struct brcmf_scan_params_le *sparams;
653 struct brcmf_ssid ssid;
654
655 memsize += num_chans * sizeof(__le16);
656 memblk = kzalloc(memsize, GFP_KERNEL);
657 if (!memblk)
658 return -ENOMEM;
659
660 vif = p2p->bss_idx[bss_type].vif;
661 if (vif == NULL) {
662 brcmf_err("no vif for bss type %d\n", bss_type);
663 ret = -EINVAL;
664 goto exit;
665 }
666
667 switch (search_state) {
668 case WL_P2P_DISC_ST_SEARCH:
669 /*
670 * If we in SEARCH STATE, we don't need to set SSID explictly
671 * because dongle use P2P WILDCARD internally by default
672 */
673 /* use null ssid */
674 ssid.SSID_len = 0;
675 memset(ssid.SSID, 0, sizeof(ssid.SSID));
676 break;
677 case WL_P2P_DISC_ST_SCAN:
678 /*
679 * wpa_supplicant has p2p_find command with type social or
680 * progressive. For progressive, we need to set the ssid to
681 * P2P WILDCARD because we just do broadcast scan unless
682 * setting SSID.
683 */
684 ssid.SSID_len = BRCMF_P2P_WILDCARD_SSID_LEN;
685 memcpy(ssid.SSID, BRCMF_P2P_WILDCARD_SSID, ssid.SSID_len);
686 break;
687 default:
688 brcmf_err(" invalid search state %d\n", search_state);
689 ret = -EINVAL;
690 goto exit;
691 }
692
693 brcmf_p2p_set_discover_state(vif->ifp, search_state, 0, 0);
694
695 /*
696 * set p2p scan parameters.
697 */
698 p2p_params = (struct brcmf_p2p_scan_le *)memblk;
699 p2p_params->type = 'E';
700
701 /* determine the scan engine parameters */
702 sparams = &p2p_params->eparams.params_le;
703 sparams->bss_type = DOT11_BSSTYPE_ANY;
704 if (p2p->cfg->active_scan)
705 sparams->scan_type = 0;
706 else
707 sparams->scan_type = 1;
708
709 memset(&sparams->bssid, 0xFF, ETH_ALEN);
710 if (ssid.SSID_len)
711 memcpy(sparams->ssid_le.SSID, ssid.SSID, ssid.SSID_len);
712 sparams->ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
713 sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS);
714
715 /*
716 * SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan
717 * supported by the supplicant.
718 */
719 if (num_chans == SOCIAL_CHAN_CNT || num_chans == (SOCIAL_CHAN_CNT + 1))
720 active = P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS;
721 else if (num_chans == AF_PEER_SEARCH_CNT)
722 active = P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS;
723 else if (wl_get_vif_state_all(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED))
724 active = -1;
725 else
726 active = P2PAPI_SCAN_DWELL_TIME_MS;
727
728 /* Override scan params to find a peer for a connection */
729 if (num_chans == 1) {
730 active = WL_SCAN_CONNECT_DWELL_TIME_MS;
731 /* WAR to sync with presence period of VSDB GO.
732 * send probe request more frequently
733 */
734 nprobes = active / WL_SCAN_JOIN_PROBE_INTERVAL_MS;
735 } else {
736 nprobes = active / P2PAPI_SCAN_NPROBS_TIME_MS;
737 }
738
739 if (nprobes <= 0)
740 nprobes = 1;
741
742 brcmf_dbg(INFO, "nprobes # %d, active_time %d\n", nprobes, active);
743 sparams->active_time = cpu_to_le32(active);
744 sparams->nprobes = cpu_to_le32(nprobes);
745 sparams->passive_time = cpu_to_le32(-1);
746 sparams->channel_num = cpu_to_le32(num_chans &
747 BRCMF_SCAN_PARAMS_COUNT_MASK);
748 for (i = 0; i < num_chans; i++)
749 sparams->channel_list[i] = cpu_to_le16(chanspecs[i]);
750
751 /* set the escan specific parameters */
752 p2p_params->eparams.version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
753 p2p_params->eparams.action = cpu_to_le16(action);
754 p2p_params->eparams.sync_id = cpu_to_le16(0x1234);
755 /* perform p2p scan on primary device */
756 ret = brcmf_fil_bsscfg_data_set(vif->ifp, "p2p_scan", memblk, memsize);
757 if (!ret)
758 set_bit(BRCMF_SCAN_STATUS_BUSY, &p2p->cfg->scan_status);
759exit:
760 kfree(memblk);
761 return ret;
762}
763
764/**
765 * brcmf_p2p_run_escan() - escan callback for peer-to-peer.
766 *
767 * @cfg: driver private data for cfg80211 interface.
768 * @ndev: net device for which scan is requested.
769 * @request: scan request from cfg80211.
770 * @action: scan action.
771 *
772 * Determines the P2P discovery state based to scan request parameters and
773 * validates the channels in the request.
774 */
775static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
776 struct net_device *ndev,
777 struct cfg80211_scan_request *request,
778 u16 action)
779{
780 struct brcmf_p2p_info *p2p = &cfg->p2p;
781 s32 err = 0;
782 s32 search_state = WL_P2P_DISC_ST_SCAN;
783 struct brcmf_cfg80211_vif *vif;
784 struct net_device *dev = NULL;
785 int i, num_nodfs = 0;
786 u16 *chanspecs;
787
788 brcmf_dbg(TRACE, "enter\n");
789
790 if (!request) {
791 err = -EINVAL;
792 goto exit;
793 }
794
795 if (request->n_channels) {
796 chanspecs = kcalloc(request->n_channels, sizeof(*chanspecs),
797 GFP_KERNEL);
798 if (!chanspecs) {
799 err = -ENOMEM;
800 goto exit;
801 }
802 vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
803 if (vif)
804 dev = vif->wdev.netdev;
805 if (request->n_channels == 3 &&
806 request->channels[0]->hw_value == SOCIAL_CHAN_1 &&
807 request->channels[1]->hw_value == SOCIAL_CHAN_2 &&
808 request->channels[2]->hw_value == SOCIAL_CHAN_3) {
809 /* SOCIAL CHANNELS 1, 6, 11 */
810 search_state = WL_P2P_DISC_ST_SEARCH;
811 brcmf_dbg(INFO, "P2P SEARCH PHASE START\n");
812 } else if (dev != NULL && vif->mode == WL_MODE_AP) {
813 /* If you are already a GO, then do SEARCH only */
814 brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n");
815 search_state = WL_P2P_DISC_ST_SEARCH;
816 } else {
817 brcmf_dbg(INFO, "P2P SCAN STATE START\n");
818 }
819
820 /*
821 * no P2P scanning on passive or DFS channels.
822 */
823 for (i = 0; i < request->n_channels; i++) {
824 struct ieee80211_channel *chan = request->channels[i];
825
826 if (chan->flags & (IEEE80211_CHAN_RADAR |
827 IEEE80211_CHAN_PASSIVE_SCAN))
828 continue;
829
830 chanspecs[i] = channel_to_chanspec(chan);
831 brcmf_dbg(INFO, "%d: chan=%d, channel spec=%x\n",
832 num_nodfs, chan->hw_value, chanspecs[i]);
833 num_nodfs++;
834 }
835 err = brcmf_p2p_escan(p2p, num_nodfs, chanspecs, search_state,
836 action, P2PAPI_BSSCFG_DEVICE);
837 }
838exit:
839 if (err)
840 brcmf_err("error (%d)\n", err);
841 return err;
842}
843
844
845/**
846 * brcmf_p2p_find_listen_channel() - find listen channel in ie string.
847 *
848 * @ie: string of information elements.
849 * @ie_len: length of string.
850 *
851 * Scan ie for p2p ie and look for attribute 6 channel. If available determine
852 * channel and return it.
853 */
854static s32 brcmf_p2p_find_listen_channel(const u8 *ie, u32 ie_len)
855{
856 u8 channel_ie[5];
857 s32 listen_channel;
858 s32 err;
859
860 err = cfg80211_get_p2p_attr(ie, ie_len,
861 IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
862 channel_ie, sizeof(channel_ie));
863 if (err < 0)
864 return err;
865
866 /* listen channel subel length format: */
867 /* 3(country) + 1(op. class) + 1(chan num) */
868 listen_channel = (s32)channel_ie[3 + 1];
869
870 if (listen_channel == SOCIAL_CHAN_1 ||
871 listen_channel == SOCIAL_CHAN_2 ||
872 listen_channel == SOCIAL_CHAN_3) {
873 brcmf_dbg(INFO, "Found my Listen Channel %d\n", listen_channel);
874 return listen_channel;
875 }
876
877 return -EPERM;
878}
879
880
881/**
882 * brcmf_p2p_scan_prep() - prepare scan based on request.
883 *
884 * @wiphy: wiphy device.
885 * @request: scan request from cfg80211.
886 * @vif: vif on which scan request is to be executed.
887 *
888 * Prepare the scan appropriately for type of scan requested. Overrides the
889 * escan .run() callback for peer-to-peer scanning.
890 */
891int brcmf_p2p_scan_prep(struct wiphy *wiphy,
892 struct cfg80211_scan_request *request,
893 struct brcmf_cfg80211_vif *vif)
894{
895 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
896 struct brcmf_p2p_info *p2p = &cfg->p2p;
897 int err = 0;
898
899 if (brcmf_p2p_scan_is_p2p_request(request)) {
900 /* find my listen channel */
901 err = brcmf_p2p_find_listen_channel(request->ie,
902 request->ie_len);
903 if (err < 0)
904 return err;
905
906 p2p->afx_hdl.my_listen_chan = err;
907
908 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
909 brcmf_dbg(INFO, "P2P: GO_NEG_PHASE status cleared\n");
910
911 err = brcmf_p2p_enable_discovery(p2p);
912 if (err)
913 return err;
914
915 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
916
917 /* override .run_escan() callback. */
918 cfg->escan_info.run = brcmf_p2p_run_escan;
919 }
920 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
921 request->ie, request->ie_len);
922 return err;
923}
924
925
926/**
927 * brcmf_p2p_discover_listen() - set firmware to discover listen state.
928 *
929 * @p2p: p2p device.
930 * @channel: channel nr for discover listen.
931 * @duration: time in ms to stay on channel.
932 *
933 */
934static s32
935brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration)
936{
937 struct brcmf_cfg80211_vif *vif;
938 s32 err = 0;
939 u16 chanspec;
940
941 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
942 if (!vif) {
943 brcmf_err("Discovery is not set, so we have nothing to do\n");
944 err = -EPERM;
945 goto exit;
946 }
947
948 if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status)) {
949 brcmf_err("Previous LISTEN is not completed yet\n");
950 /* WAR: prevent cookie mismatch in wpa_supplicant return OK */
951 goto exit;
952 }
953
954 chanspec = brcmf_p2p_chnr_to_chspec(channel);
955 err = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_LISTEN,
956 chanspec, (u16)duration);
957 if (!err) {
958 set_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status);
959 p2p->remain_on_channel_cookie++;
960 }
961exit:
962 return err;
963}
964
965
966/**
967 * brcmf_p2p_remain_on_channel() - put device on channel and stay there.
968 *
969 * @wiphy: wiphy device.
970 * @channel: channel to stay on.
971 * @duration: time in ms to remain on channel.
972 *
973 */
974int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
975 struct ieee80211_channel *channel,
976 unsigned int duration, u64 *cookie)
977{
978 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
979 struct brcmf_p2p_info *p2p = &cfg->p2p;
980 s32 err;
981 u16 channel_nr;
982
983 channel_nr = ieee80211_frequency_to_channel(channel->center_freq);
984 brcmf_dbg(TRACE, "Enter, channel: %d, duration ms (%d)\n", channel_nr,
985 duration);
986
987 err = brcmf_p2p_enable_discovery(p2p);
988 if (err)
989 goto exit;
990 err = brcmf_p2p_discover_listen(p2p, channel_nr, duration);
991 if (err)
992 goto exit;
993
994 memcpy(&p2p->remain_on_channel, channel, sizeof(*channel));
995 *cookie = p2p->remain_on_channel_cookie;
996 cfg80211_ready_on_channel(wdev, *cookie, channel, duration, GFP_KERNEL);
997
998exit:
999 return err;
1000}
1001
1002
1003/**
1004 * brcmf_p2p_notify_listen_complete() - p2p listen has completed.
1005 *
1006 * @ifp: interfac control.
1007 * @e: event message. Not used, to make it usable for fweh event dispatcher.
1008 * @data: payload of message. Not used.
1009 *
1010 */
1011int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
1012 const struct brcmf_event_msg *e,
1013 void *data)
1014{
1015 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1016 struct brcmf_p2p_info *p2p = &cfg->p2p;
1017
1018 brcmf_dbg(TRACE, "Enter\n");
1019 if (test_and_clear_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN,
1020 &p2p->status)) {
1021 if (test_and_clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1022 &p2p->status)) {
1023 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
1024 &p2p->status);
1025 brcmf_dbg(INFO, "Listen DONE, wake up wait_next_af\n");
1026 complete(&p2p->wait_next_af);
1027 }
1028
1029 cfg80211_remain_on_channel_expired(&ifp->vif->wdev,
1030 p2p->remain_on_channel_cookie,
1031 &p2p->remain_on_channel,
1032 GFP_KERNEL);
1033 }
1034 return 0;
1035}
1036
1037
1038/**
1039 * brcmf_p2p_cancel_remain_on_channel() - cancel p2p listen state.
1040 *
1041 * @ifp: interfac control.
1042 *
1043 */
1044void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp)
1045{
1046 if (!ifp)
1047 return;
1048 brcmf_p2p_set_discover_state(ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
1049 brcmf_p2p_notify_listen_complete(ifp, NULL, NULL);
1050}
1051
1052
1053/**
1054 * brcmf_p2p_act_frm_search() - search function for action frame.
1055 *
1056 * @p2p: p2p device.
1057 * channel: channel on which action frame is to be trasmitted.
1058 *
1059 * search function to reach at common channel to send action frame. When
1060 * channel is 0 then all social channels will be used to send af
1061 */
1062static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel)
1063{
1064 s32 err;
1065 u32 channel_cnt;
1066 u16 *default_chan_list;
1067 u32 i;
1068
1069 brcmf_dbg(TRACE, "Enter\n");
1070
1071 if (channel)
1072 channel_cnt = AF_PEER_SEARCH_CNT;
1073 else
1074 channel_cnt = SOCIAL_CHAN_CNT;
1075 default_chan_list = kzalloc(channel_cnt * sizeof(*default_chan_list),
1076 GFP_KERNEL);
1077 if (default_chan_list == NULL) {
1078 brcmf_err("channel list allocation failed\n");
1079 err = -ENOMEM;
1080 goto exit;
1081 }
1082 if (channel) {
1083 /* insert same channel to the chan_list */
1084 for (i = 0; i < channel_cnt; i++)
1085 default_chan_list[i] =
1086 brcmf_p2p_chnr_to_chspec(channel);
1087 } else {
1088 default_chan_list[0] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_1);
1089 default_chan_list[1] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_2);
1090 default_chan_list[2] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_3);
1091 }
1092 err = brcmf_p2p_escan(p2p, channel_cnt, default_chan_list,
1093 WL_P2P_DISC_ST_SEARCH, WL_ESCAN_ACTION_START,
1094 P2PAPI_BSSCFG_DEVICE);
1095 kfree(default_chan_list);
1096exit:
1097 return err;
1098}
1099
1100
1101/**
1102 * brcmf_p2p_afx_handler() - afx worker thread.
1103 *
1104 * @work:
1105 *
1106 */
1107static void brcmf_p2p_afx_handler(struct work_struct *work)
1108{
1109 struct afx_hdl *afx_hdl = container_of(work, struct afx_hdl, afx_work);
1110 struct brcmf_p2p_info *p2p = container_of(afx_hdl,
1111 struct brcmf_p2p_info,
1112 afx_hdl);
1113 s32 err;
1114
1115 if (!afx_hdl->is_active)
1116 return;
1117
1118 if (afx_hdl->is_listen && afx_hdl->my_listen_chan)
1119 /* 100ms ~ 300ms */
1120 err = brcmf_p2p_discover_listen(p2p, afx_hdl->my_listen_chan,
1121 100 * (1 + (random32() % 3)));
1122 else
1123 err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan);
1124
1125 if (err) {
1126 brcmf_err("ERROR occurred! value is (%d)\n", err);
1127 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1128 &p2p->status))
1129 complete(&afx_hdl->act_frm_scan);
1130 }
1131}
1132
1133
1134/**
1135 * brcmf_p2p_af_searching_channel() - search channel.
1136 *
1137 * @p2p: p2p device info struct.
1138 *
1139 */
1140static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p)
1141{
1142 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1143 struct brcmf_cfg80211_vif *pri_vif;
1144 unsigned long duration;
1145 s32 retry;
1146
1147 brcmf_dbg(TRACE, "Enter\n");
1148
1149 pri_vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1150
1151 INIT_COMPLETION(afx_hdl->act_frm_scan);
1152 set_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status);
1153 afx_hdl->is_active = true;
1154 afx_hdl->peer_chan = P2P_INVALID_CHANNEL;
1155
1156 /* Loop to wait until we find a peer's channel or the
1157 * pending action frame tx is cancelled.
1158 */
1159 retry = 0;
1160 duration = msecs_to_jiffies(P2P_AF_FRM_SCAN_MAX_WAIT);
1161 while ((retry < P2P_CHANNEL_SYNC_RETRY) &&
1162 (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)) {
1163 afx_hdl->is_listen = false;
1164 brcmf_dbg(TRACE, "Scheduling action frame for sending.. (%d)\n",
1165 retry);
1166 /* search peer on peer's listen channel */
1167 schedule_work(&afx_hdl->afx_work);
1168 wait_for_completion_timeout(&afx_hdl->act_frm_scan, duration);
1169 if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) ||
1170 (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1171 &p2p->status)))
1172 break;
1173
1174 if (afx_hdl->my_listen_chan) {
1175 brcmf_dbg(TRACE, "Scheduling listen peer, channel=%d\n",
1176 afx_hdl->my_listen_chan);
1177 /* listen on my listen channel */
1178 afx_hdl->is_listen = true;
1179 schedule_work(&afx_hdl->afx_work);
1180 wait_for_completion_timeout(&afx_hdl->act_frm_scan,
1181 duration);
1182 }
1183 if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) ||
1184 (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1185 &p2p->status)))
1186 break;
1187 retry++;
1188
1189 /* if sta is connected or connecting, sleep for a while before
1190 * retry af tx or finding a peer
1191 */
1192 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &pri_vif->sme_state) ||
1193 test_bit(BRCMF_VIF_STATUS_CONNECTING, &pri_vif->sme_state))
1194 msleep(P2P_DEFAULT_SLEEP_TIME_VSDB);
1195 }
1196
1197 brcmf_dbg(TRACE, "Completed search/listen peer_chan=%d\n",
1198 afx_hdl->peer_chan);
1199 afx_hdl->is_active = false;
1200
1201 clear_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status);
1202
1203 return afx_hdl->peer_chan;
1204}
1205
1206
1207/**
1208 * brcmf_p2p_scan_finding_common_channel() - was escan used for finding channel
1209 *
1210 * @cfg: common configuration struct.
1211 * @bi: bss info struct, result from scan.
1212 *
1213 */
1214bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
1215 struct brcmf_bss_info_le *bi)
1216
1217{
1218 struct brcmf_p2p_info *p2p = &cfg->p2p;
1219 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1220 u8 *ie;
1221 s32 err;
1222 u8 p2p_dev_addr[ETH_ALEN];
1223
1224 if (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status))
1225 return false;
1226
1227 if (bi == NULL) {
1228 brcmf_dbg(TRACE, "ACTION FRAME SCAN Done\n");
1229 if (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)
1230 complete(&afx_hdl->act_frm_scan);
1231 return true;
1232 }
1233
1234 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
1235 memset(p2p_dev_addr, 0, sizeof(p2p_dev_addr));
1236 err = cfg80211_get_p2p_attr(ie, le32_to_cpu(bi->ie_length),
1237 IEEE80211_P2P_ATTR_DEVICE_INFO,
1238 p2p_dev_addr, sizeof(p2p_dev_addr));
1239 if (err < 0)
1240 err = cfg80211_get_p2p_attr(ie, le32_to_cpu(bi->ie_length),
1241 IEEE80211_P2P_ATTR_DEVICE_ID,
1242 p2p_dev_addr, sizeof(p2p_dev_addr));
1243 if ((err >= 0) &&
1244 (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) {
1245 afx_hdl->peer_chan = bi->ctl_ch ? bi->ctl_ch :
1246 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
1247 brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
1248 afx_hdl->tx_dst_addr, afx_hdl->peer_chan);
1249 complete(&afx_hdl->act_frm_scan);
1250 }
1251 return true;
1252}
1253
1254/**
1255 * brcmf_p2p_stop_wait_next_action_frame() - finish scan if af tx complete.
1256 *
1257 * @cfg: common configuration struct.
1258 *
1259 */
1260static void
1261brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg)
1262{
1263 struct brcmf_p2p_info *p2p = &cfg->p2p;
1264 struct net_device *ndev = cfg->escan_info.ndev;
1265
1266 if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) &&
1267 (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) ||
1268 test_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status))) {
1269 brcmf_dbg(TRACE, "*** Wake UP ** abort actframe iovar\n");
1270 /* if channel is not zero, "actfame" uses off channel scan.
1271 * So abort scan for off channel completion.
1272 */
1273 if (p2p->af_sent_channel)
1274 brcmf_notify_escan_complete(cfg, ndev, true, true);
1275 } else if (test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1276 &p2p->status)) {
1277 brcmf_dbg(TRACE, "*** Wake UP ** abort listen for next af frame\n");
1278 /* So abort scan to cancel listen */
1279 brcmf_notify_escan_complete(cfg, ndev, true, true);
1280 }
1281}
1282
1283
1284/**
1285 * brcmf_p2p_gon_req_collision() - Check if go negotiaton collission
1286 *
1287 * @p2p: p2p device info struct.
1288 *
1289 * return true if recevied action frame is to be dropped.
1290 */
1291static bool
1292brcmf_p2p_gon_req_collision(struct brcmf_p2p_info *p2p, u8 *mac)
1293{
1294 struct brcmf_cfg80211_info *cfg = p2p->cfg;
1295 struct brcmf_if *ifp;
1296
1297 brcmf_dbg(TRACE, "Enter\n");
1298
1299 if (!test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) ||
1300 !p2p->gon_req_action)
1301 return false;
1302
1303 brcmf_dbg(TRACE, "GO Negotiation Request COLLISION !!!\n");
1304 /* if sa(peer) addr is less than da(my) addr, then this device
1305 * process peer's gon request and block to send gon req.
1306 * if not (sa addr > da addr),
1307 * this device will process gon request and drop gon req of peer.
1308 */
1309 ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
1310 if (memcmp(mac, ifp->mac_addr, ETH_ALEN) < 0) {
1311 brcmf_dbg(INFO, "Block transmit gon req !!!\n");
1312 p2p->block_gon_req_tx = true;
1313 /* if we are finding a common channel for sending af,
1314 * do not scan more to block to send current gon req
1315 */
1316 if (test_and_clear_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1317 &p2p->status))
1318 complete(&p2p->afx_hdl.act_frm_scan);
1319 if (test_and_clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
1320 &p2p->status))
1321 brcmf_p2p_stop_wait_next_action_frame(cfg);
1322 return false;
1323 }
1324
1325 /* drop gon request of peer to process gon request by this device. */
1326 brcmf_dbg(INFO, "Drop received gon req !!!\n");
1327
1328 return true;
1329}
1330
1331
1332/**
1333 * brcmf_p2p_notify_action_frame_rx() - received action frame.
1334 *
1335 * @ifp: interfac control.
1336 * @e: event message. Not used, to make it usable for fweh event dispatcher.
1337 * @data: payload of message, containing action frame data.
1338 *
1339 */
1340int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
1341 const struct brcmf_event_msg *e,
1342 void *data)
1343{
1344 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1345 struct brcmf_p2p_info *p2p = &cfg->p2p;
1346 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1347 struct wireless_dev *wdev;
1348 u32 mgmt_frame_len = e->datalen - sizeof(struct brcmf_rx_mgmt_data);
1349 struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
1350 u8 *frame = (u8 *)(rxframe + 1);
1351 struct brcmf_p2p_pub_act_frame *act_frm;
1352 struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm;
1353 u16 chanspec = be16_to_cpu(rxframe->chanspec);
1354 struct ieee80211_mgmt *mgmt_frame;
1355 s32 freq;
1356 u16 mgmt_type;
1357 u8 action;
1358
1359 /* Check if wpa_supplicant has registered for this frame */
1360 brcmf_dbg(INFO, "ifp->vif->mgmt_rx_reg %04x\n", ifp->vif->mgmt_rx_reg);
1361 mgmt_type = (IEEE80211_STYPE_ACTION & IEEE80211_FCTL_STYPE) >> 4;
1362 if ((ifp->vif->mgmt_rx_reg & BIT(mgmt_type)) == 0)
1363 return 0;
1364
1365 brcmf_p2p_print_actframe(false, frame, mgmt_frame_len);
1366
1367 action = P2P_PAF_SUBTYPE_INVALID;
1368 if (brcmf_p2p_is_pub_action(frame, mgmt_frame_len)) {
1369 act_frm = (struct brcmf_p2p_pub_act_frame *)frame;
1370 action = act_frm->subtype;
1371 if ((action == P2P_PAF_GON_REQ) &&
1372 (brcmf_p2p_gon_req_collision(p2p, (u8 *)e->addr))) {
1373 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1374 &p2p->status) &&
1375 (memcmp(afx_hdl->tx_dst_addr, e->addr,
1376 ETH_ALEN) == 0)) {
1377 afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec);
1378 brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
1379 afx_hdl->peer_chan);
1380 complete(&afx_hdl->act_frm_scan);
1381 }
1382 return 0;
1383 }
1384 /* After complete GO Negotiation, roll back to mpc mode */
1385 if ((action == P2P_PAF_GON_CONF) ||
1386 (action == P2P_PAF_PROVDIS_RSP))
1387 brcmf_set_mpc(ifp->ndev, 1);
1388 if (action == P2P_PAF_GON_CONF) {
1389 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status cleared\n");
1390 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1391 }
1392 } else if (brcmf_p2p_is_gas_action(frame, mgmt_frame_len)) {
1393 sd_act_frm = (struct brcmf_p2psd_gas_pub_act_frame *)frame;
1394 action = sd_act_frm->action;
1395 }
1396
1397 if (test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) &&
1398 (p2p->next_af_subtype == action)) {
1399 brcmf_dbg(TRACE, "We got a right next frame! (%d)\n", action);
1400 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
1401 &p2p->status);
1402 /* Stop waiting for next AF. */
1403 brcmf_p2p_stop_wait_next_action_frame(cfg);
1404 }
1405
1406 mgmt_frame = kzalloc(offsetof(struct ieee80211_mgmt, u) +
1407 mgmt_frame_len, GFP_KERNEL);
1408 if (!mgmt_frame) {
1409 brcmf_err("No memory available for action frame\n");
1410 return -ENOMEM;
1411 }
1412 memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN);
1413 brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mgmt_frame->bssid,
1414 ETH_ALEN);
1415 memcpy(mgmt_frame->sa, e->addr, ETH_ALEN);
1416 mgmt_frame->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
1417 memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
1418 mgmt_frame_len += offsetof(struct ieee80211_mgmt, u);
1419
1420 freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec),
1421 CHSPEC_IS2G(chanspec) ?
1422 IEEE80211_BAND_2GHZ :
1423 IEEE80211_BAND_5GHZ);
1424 wdev = ifp->ndev->ieee80211_ptr;
1425 cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len,
1426 GFP_ATOMIC);
1427
1428 kfree(mgmt_frame);
1429 return 0;
1430}
1431
1432
1433/**
1434 * brcmf_p2p_notify_action_tx_complete() - transmit action frame complete
1435 *
1436 * @ifp: interfac control.
1437 * @e: event message. Not used, to make it usable for fweh event dispatcher.
1438 * @data: not used.
1439 *
1440 */
1441int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
1442 const struct brcmf_event_msg *e,
1443 void *data)
1444{
1445 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1446 struct brcmf_p2p_info *p2p = &cfg->p2p;
1447
1448 brcmf_dbg(INFO, "Enter: event %s, status=%d\n",
1449 e->event_code == BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE ?
1450 "ACTION_FRAME_OFF_CHAN_COMPLETE" : "ACTION_FRAME_COMPLETE",
1451 e->status);
1452
1453 if (!test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status))
1454 return 0;
1455
1456 if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) {
1457 if (e->status == BRCMF_E_STATUS_SUCCESS)
1458 set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED,
1459 &p2p->status);
1460 else {
1461 set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
1462 /* If there is no ack, we don't need to wait for
1463 * WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event
1464 */
1465 brcmf_p2p_stop_wait_next_action_frame(cfg);
1466 }
1467
1468 } else {
1469 complete(&p2p->send_af_done);
1470 }
1471 return 0;
1472}
1473
1474
1475/**
1476 * brcmf_p2p_tx_action_frame() - send action frame over fil.
1477 *
1478 * @p2p: p2p info struct for vif.
1479 * @af_params: action frame data/info.
1480 *
1481 * Send an action frame immediately without doing channel synchronization.
1482 *
1483 * This function waits for a completion event before returning.
1484 * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action
1485 * frame is transmitted.
1486 */
1487static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
1488 struct brcmf_fil_af_params_le *af_params)
1489{
1490 struct brcmf_cfg80211_vif *vif;
1491 s32 err = 0;
1492 s32 timeout = 0;
1493
1494 brcmf_dbg(TRACE, "Enter\n");
1495
1496 INIT_COMPLETION(p2p->send_af_done);
1497 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
1498 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
1499
1500 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
1501 err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
1502 sizeof(*af_params));
1503 if (err) {
1504 brcmf_err(" sending action frame has failed\n");
1505 goto exit;
1506 }
1507
1508 p2p->af_sent_channel = le32_to_cpu(af_params->channel);
1509 p2p->af_tx_sent_jiffies = jiffies;
1510
1511 timeout = wait_for_completion_timeout(&p2p->send_af_done,
1512 msecs_to_jiffies(P2P_AF_MAX_WAIT_TIME));
1513
1514 if (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status)) {
1515 brcmf_dbg(TRACE, "TX action frame operation is success\n");
1516 } else {
1517 err = -EIO;
1518 brcmf_dbg(TRACE, "TX action frame operation has failed\n");
1519 }
1520 /* clear status bit for action tx */
1521 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
1522 clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
1523
1524exit:
1525 return err;
1526}
1527
1528
1529/**
1530 * brcmf_p2p_pub_af_tx() - public action frame tx routine.
1531 *
1532 * @cfg: driver private data for cfg80211 interface.
1533 * @af_params: action frame data/info.
1534 * @config_af_params: configuration data for action frame.
1535 *
1536 * routine which transmits ation frame public type.
1537 */
1538static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg,
1539 struct brcmf_fil_af_params_le *af_params,
1540 struct brcmf_config_af_params *config_af_params)
1541{
1542 struct brcmf_p2p_info *p2p = &cfg->p2p;
1543 struct brcmf_fil_action_frame_le *action_frame;
1544 struct brcmf_p2p_pub_act_frame *act_frm;
1545 s32 err = 0;
1546 u16 ie_len;
1547
1548 action_frame = &af_params->action_frame;
1549 act_frm = (struct brcmf_p2p_pub_act_frame *)(action_frame->data);
1550
1551 config_af_params->extra_listen = true;
1552
1553 switch (act_frm->subtype) {
1554 case P2P_PAF_GON_REQ:
1555 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status set\n");
1556 set_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1557 config_af_params->mpc_onoff = 0;
1558 config_af_params->search_channel = true;
1559 p2p->next_af_subtype = act_frm->subtype + 1;
1560 p2p->gon_req_action = true;
1561 /* increase dwell time to wait for RESP frame */
1562 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1563 break;
1564 case P2P_PAF_GON_RSP:
1565 p2p->next_af_subtype = act_frm->subtype + 1;
1566 /* increase dwell time to wait for CONF frame */
1567 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1568 break;
1569 case P2P_PAF_GON_CONF:
1570 /* If we reached till GO Neg confirmation reset the filter */
1571 brcmf_dbg(TRACE, "P2P: GO_NEG_PHASE status cleared\n");
1572 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1573 /* turn on mpc again if go nego is done */
1574 config_af_params->mpc_onoff = 1;
1575 /* minimize dwell time */
1576 af_params->dwell_time = cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1577 config_af_params->extra_listen = false;
1578 break;
1579 case P2P_PAF_INVITE_REQ:
1580 config_af_params->search_channel = true;
1581 p2p->next_af_subtype = act_frm->subtype + 1;
1582 /* increase dwell time */
1583 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1584 break;
1585 case P2P_PAF_INVITE_RSP:
1586 /* minimize dwell time */
1587 af_params->dwell_time = cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1588 config_af_params->extra_listen = false;
1589 break;
1590 case P2P_PAF_DEVDIS_REQ:
1591 config_af_params->search_channel = true;
1592 p2p->next_af_subtype = act_frm->subtype + 1;
1593 /* maximize dwell time to wait for RESP frame */
1594 af_params->dwell_time = cpu_to_le32(P2P_AF_LONG_DWELL_TIME);
1595 break;
1596 case P2P_PAF_DEVDIS_RSP:
1597 /* minimize dwell time */
1598 af_params->dwell_time = cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1599 config_af_params->extra_listen = false;
1600 break;
1601 case P2P_PAF_PROVDIS_REQ:
1602 ie_len = le16_to_cpu(action_frame->len) -
1603 offsetof(struct brcmf_p2p_pub_act_frame, elts);
1604 if (cfg80211_get_p2p_attr(&act_frm->elts[0], ie_len,
1605 IEEE80211_P2P_ATTR_GROUP_ID,
1606 NULL, 0) < 0)
1607 config_af_params->search_channel = true;
1608 config_af_params->mpc_onoff = 0;
1609 p2p->next_af_subtype = act_frm->subtype + 1;
1610 /* increase dwell time to wait for RESP frame */
1611 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1612 break;
1613 case P2P_PAF_PROVDIS_RSP:
1614 /* wpa_supplicant send go nego req right after prov disc */
1615 p2p->next_af_subtype = P2P_PAF_GON_REQ;
1616 /* increase dwell time to MED level */
1617 af_params->dwell_time = cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1618 config_af_params->extra_listen = false;
1619 break;
1620 default:
1621 brcmf_err("Unknown p2p pub act frame subtype: %d\n",
1622 act_frm->subtype);
1623 err = -EINVAL;
1624 }
1625 return err;
1626}
1627
1628/**
1629 * brcmf_p2p_send_action_frame() - send action frame .
1630 *
1631 * @cfg: driver private data for cfg80211 interface.
1632 * @ndev: net device to transmit on.
1633 * @af_params: configuration data for action frame.
1634 */
1635bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
1636 struct net_device *ndev,
1637 struct brcmf_fil_af_params_le *af_params)
1638{
1639 struct brcmf_p2p_info *p2p = &cfg->p2p;
1640 struct brcmf_fil_action_frame_le *action_frame;
1641 struct brcmf_config_af_params config_af_params;
1642 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1643 u16 action_frame_len;
1644 bool ack = false;
1645 u8 category;
1646 u8 action;
1647 s32 tx_retry;
1648 s32 extra_listen_time;
1649 uint delta_ms;
1650
1651 action_frame = &af_params->action_frame;
1652 action_frame_len = le16_to_cpu(action_frame->len);
1653
1654 brcmf_p2p_print_actframe(true, action_frame->data, action_frame_len);
1655
1656 /* Add the default dwell time. Dwell time to stay off-channel */
1657 /* to wait for a response action frame after transmitting an */
1658 /* GO Negotiation action frame */
1659 af_params->dwell_time = cpu_to_le32(P2P_AF_DWELL_TIME);
1660
1661 category = action_frame->data[DOT11_ACTION_CAT_OFF];
1662 action = action_frame->data[DOT11_ACTION_ACT_OFF];
1663
1664 /* initialize variables */
1665 p2p->next_af_subtype = P2P_PAF_SUBTYPE_INVALID;
1666 p2p->gon_req_action = false;
1667
1668 /* config parameters */
1669 config_af_params.mpc_onoff = -1;
1670 config_af_params.search_channel = false;
1671 config_af_params.extra_listen = false;
1672
1673 if (brcmf_p2p_is_pub_action(action_frame->data, action_frame_len)) {
1674 /* p2p public action frame process */
1675 if (brcmf_p2p_pub_af_tx(cfg, af_params, &config_af_params)) {
1676 /* Just send unknown subtype frame with */
1677 /* default parameters. */
1678 brcmf_err("P2P Public action frame, unknown subtype.\n");
1679 }
1680 } else if (brcmf_p2p_is_gas_action(action_frame->data,
1681 action_frame_len)) {
1682 /* service discovery process */
1683 if (action == P2PSD_ACTION_ID_GAS_IREQ ||
1684 action == P2PSD_ACTION_ID_GAS_CREQ) {
1685 /* configure service discovery query frame */
1686 config_af_params.search_channel = true;
1687
1688 /* save next af suptype to cancel */
1689 /* remaining dwell time */
1690 p2p->next_af_subtype = action + 1;
1691
1692 af_params->dwell_time =
1693 cpu_to_le32(P2P_AF_MED_DWELL_TIME);
1694 } else if (action == P2PSD_ACTION_ID_GAS_IRESP ||
1695 action == P2PSD_ACTION_ID_GAS_CRESP) {
1696 /* configure service discovery response frame */
1697 af_params->dwell_time =
1698 cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
1699 } else {
1700 brcmf_err("Unknown action type: %d\n", action);
1701 goto exit;
1702 }
1703 } else if (brcmf_p2p_is_p2p_action(action_frame->data,
1704 action_frame_len)) {
1705 /* do not configure anything. it will be */
1706 /* sent with a default configuration */
1707 } else {
1708 brcmf_err("Unknown Frame: category 0x%x, action 0x%x\n",
1709 category, action);
1710 return false;
1711 }
1712
1713 /* if connecting on primary iface, sleep for a while before sending
1714 * af tx for VSDB
1715 */
1716 if (test_bit(BRCMF_VIF_STATUS_CONNECTING,
1717 &p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->sme_state))
1718 msleep(50);
1719
1720 /* if scan is ongoing, abort current scan. */
1721 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
1722 brcmf_abort_scanning(cfg);
1723
1724 memcpy(afx_hdl->tx_dst_addr, action_frame->da, ETH_ALEN);
1725
1726 /* To make sure to send successfully action frame, turn off mpc */
1727 if (config_af_params.mpc_onoff == 0)
1728 brcmf_set_mpc(ndev, 0);
1729
1730 /* set status and destination address before sending af */
1731 if (p2p->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) {
1732 /* set status to cancel the remained dwell time in rx process */
1733 set_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status);
1734 }
1735
1736 p2p->af_sent_channel = 0;
1737 set_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status);
1738 /* validate channel and p2p ies */
1739 if (config_af_params.search_channel &&
1740 IS_P2P_SOCIAL_CHANNEL(le32_to_cpu(af_params->channel)) &&
1741 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {
1742 afx_hdl = &p2p->afx_hdl;
1743 afx_hdl->peer_listen_chan = le32_to_cpu(af_params->channel);
1744
1745 if (brcmf_p2p_af_searching_channel(p2p) ==
1746 P2P_INVALID_CHANNEL) {
1747 brcmf_err("Couldn't find peer's channel.\n");
1748 goto exit;
1749 }
1750
1751 /* Abort scan even for VSDB scenarios. Scan gets aborted in
1752 * firmware but after the check of piggyback algorithm. To take
1753 * care of current piggback algo, lets abort the scan here
1754 * itself.
1755 */
1756 brcmf_notify_escan_complete(cfg, ndev, true, true);
1757
1758 /* update channel */
1759 af_params->channel = cpu_to_le32(afx_hdl->peer_chan);
1760 }
1761
1762 tx_retry = 0;
1763 while (!p2p->block_gon_req_tx &&
1764 (ack == false) && (tx_retry < P2P_AF_TX_MAX_RETRY)) {
1765 ack = !brcmf_p2p_tx_action_frame(p2p, af_params);
1766 tx_retry++;
1767 }
1768 if (ack == false) {
1769 brcmf_err("Failed to send Action Frame(retry %d)\n", tx_retry);
1770 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
1771 }
1772
1773exit:
1774 clear_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status);
1775
1776 /* WAR: sometimes dongle does not keep the dwell time of 'actframe'.
1777 * if we coundn't get the next action response frame and dongle does
1778 * not keep the dwell time, go to listen state again to get next action
1779 * response frame.
1780 */
1781 if (ack && config_af_params.extra_listen && !p2p->block_gon_req_tx &&
1782 test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) &&
1783 p2p->af_sent_channel == afx_hdl->my_listen_chan) {
1784 delta_ms = jiffies_to_msecs(jiffies - p2p->af_tx_sent_jiffies);
1785 if (le32_to_cpu(af_params->dwell_time) > delta_ms)
1786 extra_listen_time = le32_to_cpu(af_params->dwell_time) -
1787 delta_ms;
1788 else
1789 extra_listen_time = 0;
1790 if (extra_listen_time > 50) {
1791 set_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1792 &p2p->status);
1793 brcmf_dbg(INFO, "Wait more time! actual af time:%d, calculated extra listen:%d\n",
1794 le32_to_cpu(af_params->dwell_time),
1795 extra_listen_time);
1796 extra_listen_time += 100;
1797 if (!brcmf_p2p_discover_listen(p2p,
1798 p2p->af_sent_channel,
1799 extra_listen_time)) {
1800 unsigned long duration;
1801
1802 extra_listen_time += 100;
1803 duration = msecs_to_jiffies(extra_listen_time);
1804 wait_for_completion_timeout(&p2p->wait_next_af,
1805 duration);
1806 }
1807 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
1808 &p2p->status);
1809 }
1810 }
1811
1812 if (p2p->block_gon_req_tx) {
1813 /* if ack is true, supplicant will wait more time(100ms).
1814 * so we will return it as a success to get more time .
1815 */
1816 p2p->block_gon_req_tx = false;
1817 ack = true;
1818 }
1819
1820 clear_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status);
1821 /* if all done, turn mpc on again */
1822 if (config_af_params.mpc_onoff == 1)
1823 brcmf_set_mpc(ndev, 1);
1824
1825 return ack;
1826}
1827
1828/**
1829 * brcmf_p2p_notify_rx_mgmt_p2p_probereq() - Event handler for p2p probe req.
1830 *
1831 * @ifp: interface pointer for which event was received.
1832 * @e: even message.
1833 * @data: payload of event message (probe request).
1834 */
1835s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1836 const struct brcmf_event_msg *e,
1837 void *data)
1838{
1839 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1840 struct brcmf_p2p_info *p2p = &cfg->p2p;
1841 struct afx_hdl *afx_hdl = &p2p->afx_hdl;
1842 struct wireless_dev *wdev;
1843 struct brcmf_cfg80211_vif *vif = ifp->vif;
1844 struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
1845 u16 chanspec = be16_to_cpu(rxframe->chanspec);
1846 u8 *mgmt_frame;
1847 u32 mgmt_frame_len;
1848 s32 freq;
1849 u16 mgmt_type;
1850
1851 brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code,
1852 e->reason);
1853
1854 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
1855 (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) {
1856 afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec);
1857 brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
1858 afx_hdl->peer_chan);
1859 complete(&afx_hdl->act_frm_scan);
1860 }
1861
1862 /* Firmware sends us two proberesponses for each idx one. At the */
1863 /* moment anything but bsscfgidx 0 is passed up to supplicant */
1864 if (e->bsscfgidx == 0)
1865 return 0;
1866
1867 /* Filter any P2P probe reqs arriving during the GO-NEG Phase */
1868 if (test_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status)) {
1869 brcmf_dbg(INFO, "Filtering P2P probe_req in GO-NEG phase\n");
1870 return 0;
1871 }
1872
1873 /* Check if wpa_supplicant has registered for this frame */
1874 brcmf_dbg(INFO, "vif->mgmt_rx_reg %04x\n", vif->mgmt_rx_reg);
1875 mgmt_type = (IEEE80211_STYPE_PROBE_REQ & IEEE80211_FCTL_STYPE) >> 4;
1876 if ((vif->mgmt_rx_reg & BIT(mgmt_type)) == 0)
1877 return 0;
1878
1879 mgmt_frame = (u8 *)(rxframe + 1);
1880 mgmt_frame_len = e->datalen - sizeof(*rxframe);
1881 freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec),
1882 CHSPEC_IS2G(chanspec) ?
1883 IEEE80211_BAND_2GHZ :
1884 IEEE80211_BAND_5GHZ);
1885 wdev = ifp->ndev->ieee80211_ptr;
1886 cfg80211_rx_mgmt(wdev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
1887
1888 brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
1889 mgmt_frame_len, e->datalen, chanspec, freq);
1890
1891 return 0;
1892}
1893
1894
1895/**
1896 * brcmf_p2p_attach() - attach for P2P.
1897 *
1898 * @cfg: driver private data for cfg80211 interface.
1899 */
1900s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
1901{
1902 struct brcmf_if *pri_ifp;
1903 struct brcmf_if *p2p_ifp;
1904 struct brcmf_cfg80211_vif *p2p_vif;
1905 struct brcmf_p2p_info *p2p;
1906 struct brcmf_pub *drvr;
1907 s32 bssidx;
1908 s32 err = 0;
1909
1910 p2p = &cfg->p2p;
1911 p2p->cfg = cfg;
1912
1913 drvr = cfg->pub;
1914
1915 pri_ifp = drvr->iflist[0];
1916 p2p_ifp = drvr->iflist[1];
1917
1918 p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
1919
1920 if (p2p_ifp) {
1921 p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
1922 false);
1923 if (IS_ERR(p2p_vif)) {
1924 brcmf_err("could not create discovery vif\n");
1925 err = -ENOMEM;
1926 goto exit;
1927 }
1928
1929 p2p_vif->ifp = p2p_ifp;
1930 p2p_ifp->vif = p2p_vif;
1931 p2p_vif->wdev.netdev = p2p_ifp->ndev;
1932 p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
1933 SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
1934
1935 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
1936
1937 brcmf_p2p_generate_bss_mac(p2p);
1938 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
1939
1940 /* Initialize P2P Discovery in the firmware */
1941 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
1942 if (err < 0) {
1943 brcmf_err("set p2p_disc error\n");
1944 brcmf_free_vif(p2p_vif);
1945 goto exit;
1946 }
1947 /* obtain bsscfg index for P2P discovery */
1948 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
1949 if (err < 0) {
1950 brcmf_err("retrieving discover bsscfg index failed\n");
1951 brcmf_free_vif(p2p_vif);
1952 goto exit;
1953 }
1954 /* Verify that firmware uses same bssidx as driver !! */
1955 if (p2p_ifp->bssidx != bssidx) {
1956 brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
1957 bssidx, p2p_ifp->bssidx);
1958 brcmf_free_vif(p2p_vif);
1959 goto exit;
1960 }
1961
1962 init_completion(&p2p->send_af_done);
1963 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
1964 init_completion(&p2p->afx_hdl.act_frm_scan);
1965 init_completion(&p2p->wait_next_af);
1966 }
1967exit:
1968 return err;
1969}
1970
1971
1972/**
1973 * brcmf_p2p_detach() - detach P2P.
1974 *
1975 * @p2p: P2P specific data.
1976 */
1977void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
1978{
1979 struct brcmf_cfg80211_vif *vif;
1980
1981 vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
1982 if (vif != NULL) {
1983 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
1984 brcmf_p2p_deinit_discovery(p2p);
1985 /* remove discovery interface */
1986 brcmf_free_vif(vif);
1987 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
1988 }
1989 /* just set it all to zero */
1990 memset(p2p, 0, sizeof(*p2p));
1991}
1992
1993/**
1994 * brcmf_p2p_get_current_chanspec() - Get current operation channel.
1995 *
1996 * @p2p: P2P specific data.
1997 * @chanspec: chanspec to be returned.
1998 */
1999static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p,
2000 u16 *chanspec)
2001{
2002 struct brcmf_if *ifp;
2003 struct brcmf_fil_chan_info_le ci;
2004 s32 err;
2005
2006 ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
2007
2008 *chanspec = 11 & WL_CHANSPEC_CHAN_MASK;
2009
2010 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci));
2011 if (!err) {
2012 *chanspec = le32_to_cpu(ci.hw_channel) & WL_CHANSPEC_CHAN_MASK;
2013 if (*chanspec < CH_MAX_2G_CHANNEL)
2014 *chanspec |= WL_CHANSPEC_BAND_2G;
2015 else
2016 *chanspec |= WL_CHANSPEC_BAND_5G;
2017 }
2018 *chanspec |= WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
2019}
2020
2021/**
2022 * Change a P2P Role.
2023 * Parameters:
2024 * @mac: MAC address of the BSS to change a role
2025 * Returns 0 if success.
2026 */
2027int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
2028 enum brcmf_fil_p2p_if_types if_type)
2029{
2030 struct brcmf_p2p_info *p2p = &cfg->p2p;
2031 struct brcmf_cfg80211_vif *vif;
2032 struct brcmf_fil_p2p_if_le if_request;
2033 s32 err;
2034 u16 chanspec;
2035
2036 brcmf_dbg(TRACE, "Enter\n");
2037
2038 vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
2039 if (!vif) {
2040 brcmf_err("vif for P2PAPI_BSSCFG_PRIMARY does not exist\n");
2041 return -EPERM;
2042 }
2043 brcmf_notify_escan_complete(cfg, vif->ifp->ndev, true, true);
2044 vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
2045 if (!vif) {
2046 brcmf_err("vif for P2PAPI_BSSCFG_CONNECTION does not exist\n");
2047 return -EPERM;
2048 }
2049 brcmf_set_mpc(vif->ifp->ndev, 0);
2050
2051 /* In concurrency case, STA may be already associated in a particular */
2052 /* channel. so retrieve the current channel of primary interface and */
2053 /* then start the virtual interface on that. */
2054 brcmf_p2p_get_current_chanspec(p2p, &chanspec);
2055
2056 if_request.type = cpu_to_le16((u16)if_type);
2057 if_request.chspec = cpu_to_le16(chanspec);
2058 memcpy(if_request.addr, p2p->int_addr, sizeof(if_request.addr));
2059
2060 brcmf_cfg80211_arm_vif_event(cfg, vif);
2061 err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request,
2062 sizeof(if_request));
2063 if (err) {
2064 brcmf_err("p2p_ifupd FAILED, err=%d\n", err);
2065 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2066 return err;
2067 }
2068 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_CHANGE,
2069 msecs_to_jiffies(1500));
2070 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2071 if (!err) {
2072 brcmf_err("No BRCMF_E_IF_CHANGE event received\n");
2073 return -EIO;
2074 }
2075
2076 err = brcmf_fil_cmd_int_set(vif->ifp, BRCMF_C_SET_SCB_TIMEOUT,
2077 BRCMF_SCB_TIMEOUT_VALUE);
2078
2079 return err;
2080}
2081
2082static int brcmf_p2p_request_p2p_if(struct brcmf_p2p_info *p2p,
2083 struct brcmf_if *ifp, u8 ea[ETH_ALEN],
2084 enum brcmf_fil_p2p_if_types iftype)
2085{
2086 struct brcmf_fil_p2p_if_le if_request;
2087 int err;
2088 u16 chanspec;
2089
2090 /* we need a default channel */
2091 brcmf_p2p_get_current_chanspec(p2p, &chanspec);
2092
2093 /* fill the firmware request */
2094 memcpy(if_request.addr, ea, ETH_ALEN);
2095 if_request.type = cpu_to_le16((u16)iftype);
2096 if_request.chspec = cpu_to_le16(chanspec);
2097
2098 err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request,
2099 sizeof(if_request));
2100 if (err)
2101 return err;
2102
2103 return err;
2104}
2105
2106static int brcmf_p2p_disable_p2p_if(struct brcmf_cfg80211_vif *vif)
2107{
2108 struct brcmf_cfg80211_info *cfg = wdev_to_cfg(&vif->wdev);
2109 struct net_device *pri_ndev = cfg_to_ndev(cfg);
2110 struct brcmf_if *ifp = netdev_priv(pri_ndev);
2111 u8 *addr = vif->wdev.netdev->dev_addr;
2112
2113 return brcmf_fil_iovar_data_set(ifp, "p2p_ifdis", addr, ETH_ALEN);
2114}
2115
2116static int brcmf_p2p_release_p2p_if(struct brcmf_cfg80211_vif *vif)
2117{
2118 struct brcmf_cfg80211_info *cfg = wdev_to_cfg(&vif->wdev);
2119 struct net_device *pri_ndev = cfg_to_ndev(cfg);
2120 struct brcmf_if *ifp = netdev_priv(pri_ndev);
2121 u8 *addr = vif->wdev.netdev->dev_addr;
2122
2123 return brcmf_fil_iovar_data_set(ifp, "p2p_ifdel", addr, ETH_ALEN);
2124}
2125
2126/**
2127 * brcmf_p2p_add_vif() - create a new P2P virtual interface.
2128 *
2129 * @wiphy: wiphy device of new interface.
2130 * @name: name of the new interface.
2131 * @type: nl80211 interface type.
2132 * @flags: TBD
2133 * @params: TBD
2134 */
2135struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2136 enum nl80211_iftype type, u32 *flags,
2137 struct vif_params *params)
2138{
2139 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2140 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2141 struct brcmf_cfg80211_vif *vif;
2142 enum brcmf_fil_p2p_if_types iftype;
2143 enum wl_mode mode;
2144 int err;
2145
2146 if (brcmf_cfg80211_vif_event_armed(cfg))
2147 return ERR_PTR(-EBUSY);
2148
2149 brcmf_dbg(INFO, "adding vif \"%s\" (type=%d)\n", name, type);
2150
2151 switch (type) {
2152 case NL80211_IFTYPE_P2P_CLIENT:
2153 iftype = BRCMF_FIL_P2P_IF_CLIENT;
2154 mode = WL_MODE_BSS;
2155 break;
2156 case NL80211_IFTYPE_P2P_GO:
2157 iftype = BRCMF_FIL_P2P_IF_GO;
2158 mode = WL_MODE_AP;
2159 break;
2160 default:
2161 return ERR_PTR(-EOPNOTSUPP);
2162 }
2163
2164 vif = brcmf_alloc_vif(cfg, type, false);
2165 if (IS_ERR(vif))
2166 return (struct wireless_dev *)vif;
2167 brcmf_cfg80211_arm_vif_event(cfg, vif);
2168
2169 err = brcmf_p2p_request_p2p_if(&cfg->p2p, ifp, cfg->p2p.int_addr,
2170 iftype);
2171 if (err) {
2172 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2173 goto fail;
2174 }
2175
2176 /* wait for firmware event */
2177 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
2178 msecs_to_jiffies(1500));
2179 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2180 if (!err) {
2181 brcmf_err("timeout occurred\n");
2182 err = -EIO;
2183 goto fail;
2184 }
2185
2186 /* interface created in firmware */
2187 ifp = vif->ifp;
2188 if (!ifp) {
2189 brcmf_err("no if pointer provided\n");
2190 err = -ENOENT;
2191 goto fail;
2192 }
2193
2194 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
2195 err = brcmf_net_attach(ifp, true);
2196 if (err) {
2197 brcmf_err("Registering netdevice failed\n");
2198 goto fail;
2199 }
2200 cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
2201 /* Disable firmware roaming for P2P interface */
2202 brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
2203 if (iftype == BRCMF_FIL_P2P_IF_GO) {
2204 /* set station timeout for p2p */
2205 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCB_TIMEOUT,
2206 BRCMF_SCB_TIMEOUT_VALUE);
2207 }
2208 return &ifp->vif->wdev;
2209
2210fail:
2211 brcmf_free_vif(vif);
2212 return ERR_PTR(err);
2213}
2214
2215/**
2216 * brcmf_p2p_del_vif() - delete a P2P virtual interface.
2217 *
2218 * @wiphy: wiphy device of interface.
2219 * @wdev: wireless device of interface.
2220 *
2221 * TODO: not yet supported.
2222 */
2223int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2224{
2225 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2226 struct brcmf_p2p_info *p2p = &cfg->p2p;
2227 struct brcmf_cfg80211_vif *vif;
2228 unsigned long jiffie_timeout = msecs_to_jiffies(1500);
2229 bool wait_for_disable = false;
2230 int err;
2231
2232 brcmf_dbg(TRACE, "delete P2P vif\n");
2233 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
2234
2235 switch (vif->wdev.iftype) {
2236 case NL80211_IFTYPE_P2P_CLIENT:
2237 if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state))
2238 wait_for_disable = true;
2239 break;
2240
2241 case NL80211_IFTYPE_P2P_GO:
2242 if (!brcmf_p2p_disable_p2p_if(vif))
2243 wait_for_disable = true;
2244 break;
2245
2246 case NL80211_IFTYPE_P2P_DEVICE:
2247 default:
2248 return -ENOTSUPP;
2249 break;
2250 }
2251
2252 clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
2253 brcmf_dbg(INFO, "P2P: GO_NEG_PHASE status cleared\n");
2254
2255 if (wait_for_disable)
2256 wait_for_completion_timeout(&cfg->vif_disabled,
2257 msecs_to_jiffies(500));
2258
2259 brcmf_vif_clear_mgmt_ies(vif);
2260
2261 brcmf_cfg80211_arm_vif_event(cfg, vif);
2262 err = brcmf_p2p_release_p2p_if(vif);
2263 if (!err) {
2264 /* wait for firmware event */
2265 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
2266 jiffie_timeout);
2267 if (!err)
2268 err = -EIO;
2269 else
2270 err = 0;
2271 }
2272 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2273 brcmf_free_vif(vif);
2274 p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
2275
2276 return err;
2277}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
new file mode 100644
index 000000000000..6821b26224be
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
@@ -0,0 +1,183 @@
1/*
2 * Copyright (c) 2012 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 WL_CFGP2P_H_
17#define WL_CFGP2P_H_
18
19#include <net/cfg80211.h>
20
21struct brcmf_cfg80211_info;
22
23/**
24 * enum p2p_bss_type - different type of BSS configurations.
25 *
26 * @P2PAPI_BSSCFG_PRIMARY: maps to driver's primary bsscfg.
27 * @P2PAPI_BSSCFG_DEVICE: maps to driver's P2P device discovery bsscfg.
28 * @P2PAPI_BSSCFG_CONNECTION: maps to driver's P2P connection bsscfg.
29 * @P2PAPI_BSSCFG_MAX: used for range checking.
30 */
31enum p2p_bss_type {
32 P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
33 P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
34 P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
35 P2PAPI_BSSCFG_MAX
36};
37
38/**
39 * struct p2p_bss - peer-to-peer bss related information.
40 *
41 * @vif: virtual interface of this P2P bss.
42 * @private_data: TBD
43 */
44struct p2p_bss {
45 struct brcmf_cfg80211_vif *vif;
46 void *private_data;
47};
48
49/**
50 * enum brcmf_p2p_status - P2P specific dongle status.
51 *
52 * @BRCMF_P2P_STATUS_IF_ADD: peer-to-peer vif add sent to dongle.
53 * @BRCMF_P2P_STATUS_IF_DEL: NOT-USED?
54 * @BRCMF_P2P_STATUS_IF_DELETING: peer-to-peer vif delete sent to dongle.
55 * @BRCMF_P2P_STATUS_IF_CHANGING: peer-to-peer vif change sent to dongle.
56 * @BRCMF_P2P_STATUS_IF_CHANGED: peer-to-peer vif change completed on dongle.
57 * @BRCMF_P2P_STATUS_ACTION_TX_COMPLETED: action frame tx completed.
58 * @BRCMF_P2P_STATUS_ACTION_TX_NOACK: action frame tx not acked.
59 * @BRCMF_P2P_STATUS_GO_NEG_PHASE: P2P GO negotiation ongoing.
60 * @BRCMF_P2P_STATUS_DISCOVER_LISTEN: P2P listen, remaining on channel.
61 * @BRCMF_P2P_STATUS_SENDING_ACT_FRAME: In the process of sending action frame.
62 * @BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN: extra listen time for af tx.
63 * @BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME: waiting for action frame response.
64 * @BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL: search channel for AF active.
65 */
66enum brcmf_p2p_status {
67 BRCMF_P2P_STATUS_ENABLED,
68 BRCMF_P2P_STATUS_IF_ADD,
69 BRCMF_P2P_STATUS_IF_DEL,
70 BRCMF_P2P_STATUS_IF_DELETING,
71 BRCMF_P2P_STATUS_IF_CHANGING,
72 BRCMF_P2P_STATUS_IF_CHANGED,
73 BRCMF_P2P_STATUS_ACTION_TX_COMPLETED,
74 BRCMF_P2P_STATUS_ACTION_TX_NOACK,
75 BRCMF_P2P_STATUS_GO_NEG_PHASE,
76 BRCMF_P2P_STATUS_DISCOVER_LISTEN,
77 BRCMF_P2P_STATUS_SENDING_ACT_FRAME,
78 BRCMF_P2P_STATUS_WAITING_NEXT_AF_LISTEN,
79 BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME,
80 BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL
81};
82
83/**
84 * struct afx_hdl - action frame off channel storage.
85 *
86 * @afx_work: worker thread for searching channel
87 * @act_frm_scan: thread synchronizing struct.
88 * @is_active: channel searching active.
89 * @peer_chan: current channel.
90 * @is_listen: sets mode for afx worker.
91 * @my_listen_chan: this peers listen channel.
92 * @peer_listen_chan: remote peers listen channel.
93 * @tx_dst_addr: mac address where tx af should be sent to.
94 */
95struct afx_hdl {
96 struct work_struct afx_work;
97 struct completion act_frm_scan;
98 bool is_active;
99 s32 peer_chan;
100 bool is_listen;
101 u16 my_listen_chan;
102 u16 peer_listen_chan;
103 u8 tx_dst_addr[ETH_ALEN];
104};
105
106/**
107 * struct brcmf_p2p_info - p2p specific driver information.
108 *
109 * @cfg: driver private data for cfg80211 interface.
110 * @status: status of P2P (see enum brcmf_p2p_status).
111 * @dev_addr: P2P device address.
112 * @int_addr: P2P interface address.
113 * @bss_idx: informate for P2P bss types.
114 * @listen_timer: timer for @WL_P2P_DISC_ST_LISTEN discover state.
115 * @ssid: ssid for P2P GO.
116 * @listen_channel: channel for @WL_P2P_DISC_ST_LISTEN discover state.
117 * @remain_on_channel: contains copy of struct used by cfg80211.
118 * @remain_on_channel_cookie: cookie counter for remain on channel cmd
119 * @next_af_subtype: expected action frame subtype.
120 * @send_af_done: indication that action frame tx is complete.
121 * @afx_hdl: action frame search handler info.
122 * @af_sent_channel: channel action frame is sent.
123 * @af_tx_sent_jiffies: jiffies time when af tx was transmitted.
124 * @wait_next_af: thread synchronizing struct.
125 * @gon_req_action: about to send go negotiation requets frame.
126 * @block_gon_req_tx: drop tx go negotiation requets frame.
127 */
128struct brcmf_p2p_info {
129 struct brcmf_cfg80211_info *cfg;
130 unsigned long status;
131 u8 dev_addr[ETH_ALEN];
132 u8 int_addr[ETH_ALEN];
133 struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
134 struct timer_list listen_timer;
135 struct brcmf_ssid ssid;
136 u8 listen_channel;
137 struct ieee80211_channel remain_on_channel;
138 u32 remain_on_channel_cookie;
139 u8 next_af_subtype;
140 struct completion send_af_done;
141 struct afx_hdl afx_hdl;
142 u32 af_sent_channel;
143 unsigned long af_tx_sent_jiffies;
144 struct completion wait_next_af;
145 bool gon_req_action;
146 bool block_gon_req_tx;
147};
148
149s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg);
150void brcmf_p2p_detach(struct brcmf_p2p_info *p2p);
151struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
152 enum nl80211_iftype type, u32 *flags,
153 struct vif_params *params);
154int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);
155int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
156 enum brcmf_fil_p2p_if_types if_type);
157int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev);
158void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev);
159int brcmf_p2p_scan_prep(struct wiphy *wiphy,
160 struct cfg80211_scan_request *request,
161 struct brcmf_cfg80211_vif *vif);
162int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
163 struct ieee80211_channel *channel,
164 unsigned int duration, u64 *cookie);
165int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
166 const struct brcmf_event_msg *e,
167 void *data);
168void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp);
169int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
170 const struct brcmf_event_msg *e,
171 void *data);
172int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
173 const struct brcmf_event_msg *e,
174 void *data);
175bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
176 struct net_device *ndev,
177 struct brcmf_fil_af_params_le *af_params);
178bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
179 struct brcmf_bss_info_le *bi);
180s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
181 const struct brcmf_event_msg *e,
182 void *data);
183#endif /* WL_CFGP2P_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index bc5a042c9a96..42289e9ea886 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -420,10 +420,6 @@ static void brcmf_usb_tx_complete(struct urb *urb)
420 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, 420 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
421 req->skb); 421 req->skb);
422 brcmf_usb_del_fromq(devinfo, req); 422 brcmf_usb_del_fromq(devinfo, req);
423 if (urb->status == 0)
424 devinfo->bus_pub.bus->dstats.tx_packets++;
425 else
426 devinfo->bus_pub.bus->dstats.tx_errors++;
427 423
428 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0); 424 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
429 425
@@ -450,10 +446,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
450 req->skb = NULL; 446 req->skb = NULL;
451 447
452 /* zero lenght packets indicate usb "failure". Do not refill */ 448 /* zero lenght packets indicate usb "failure". Do not refill */
453 if (urb->status == 0 && urb->actual_length) { 449 if (urb->status != 0 || !urb->actual_length) {
454 devinfo->bus_pub.bus->dstats.rx_packets++;
455 } else {
456 devinfo->bus_pub.bus->dstats.rx_errors++;
457 brcmu_pkt_buf_free_skb(skb); 450 brcmu_pkt_buf_free_skb(skb);
458 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL); 451 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
459 return; 452 return;
@@ -1256,6 +1249,8 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1256 bus->bus_priv.usb = bus_pub; 1249 bus->bus_priv.usb = bus_pub;
1257 dev_set_drvdata(dev, bus); 1250 dev_set_drvdata(dev, bus);
1258 bus->ops = &brcmf_usb_bus_ops; 1251 bus->ops = &brcmf_usb_bus_ops;
1252 bus->chip = bus_pub->devid;
1253 bus->chiprev = bus_pub->chiprev;
1259 1254
1260 /* Attach to the common driver interface */ 1255 /* Attach to the common driver interface */
1261 ret = brcmf_attach(0, dev); 1256 ret = brcmf_attach(0, dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 62a528e8b958..cecc3eff72e9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -26,6 +26,8 @@
26#include <brcmu_wifi.h> 26#include <brcmu_wifi.h>
27#include "dhd.h" 27#include "dhd.h"
28#include "dhd_dbg.h" 28#include "dhd_dbg.h"
29#include "fwil_types.h"
30#include "p2p.h"
29#include "wl_cfg80211.h" 31#include "wl_cfg80211.h"
30#include "fwil.h" 32#include "fwil.h"
31 33
@@ -41,16 +43,13 @@
41#define BRCMF_PNO_SCAN_COMPLETE 1 43#define BRCMF_PNO_SCAN_COMPLETE 1
42#define BRCMF_PNO_SCAN_INCOMPLETE 0 44#define BRCMF_PNO_SCAN_INCOMPLETE 0
43 45
44#define BRCMF_IFACE_MAX_CNT 2 46#define BRCMF_IFACE_MAX_CNT 3
45 47
46#define TLV_LEN_OFF 1 /* length offset */
47#define TLV_HDR_LEN 2 /* header length */
48#define TLV_BODY_OFF 2 /* body offset */
49#define TLV_OUI_LEN 3 /* oui id length */
50#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ 48#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
51#define WPA_OUI_TYPE 1 49#define WPA_OUI_TYPE 1
52#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ 50#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
53#define WME_OUI_TYPE 2 51#define WME_OUI_TYPE 2
52#define WPS_OUI_TYPE 4
54 53
55#define VS_IE_FIXED_HDR_LEN 6 54#define VS_IE_FIXED_HDR_LEN 6
56#define WPA_IE_VERSION_LEN 2 55#define WPA_IE_VERSION_LEN 2
@@ -76,13 +75,15 @@
76#define VNDR_IE_PKTFLAG_OFFSET 8 75#define VNDR_IE_PKTFLAG_OFFSET 8
77#define VNDR_IE_VSIE_OFFSET 12 76#define VNDR_IE_VSIE_OFFSET 12
78#define VNDR_IE_HDR_SIZE 12 77#define VNDR_IE_HDR_SIZE 12
79#define VNDR_IE_BEACON_FLAG 0x1 78#define VNDR_IE_PARSE_LIMIT 5
80#define VNDR_IE_PRBRSP_FLAG 0x2
81#define MAX_VNDR_IE_NUMBER 5
82 79
83#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */ 80#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
84#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */ 81#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
85 82
83#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
84#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
85#define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
86
86#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ 87#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
87 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) 88 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
88 89
@@ -271,13 +272,6 @@ static const u32 __wl_cipher_suites[] = {
271 WLAN_CIPHER_SUITE_AES_CMAC, 272 WLAN_CIPHER_SUITE_AES_CMAC,
272}; 273};
273 274
274/* tag_ID/length/value_buffer tuple */
275struct brcmf_tlv {
276 u8 id;
277 u8 len;
278 u8 data[1];
279};
280
281/* Vendor specific ie. id = 221, oui and type defines exact ie */ 275/* Vendor specific ie. id = 221, oui and type defines exact ie */
282struct brcmf_vs_tlv { 276struct brcmf_vs_tlv {
283 u8 id; 277 u8 id;
@@ -294,7 +288,7 @@ struct parsed_vndr_ie_info {
294 288
295struct parsed_vndr_ies { 289struct parsed_vndr_ies {
296 u32 count; 290 u32 count;
297 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER]; 291 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
298}; 292};
299 293
300/* Quarter dBm units to mW 294/* Quarter dBm units to mW
@@ -381,7 +375,7 @@ static u8 brcmf_mw_to_qdbm(u16 mw)
381 return qdbm; 375 return qdbm;
382} 376}
383 377
384static u16 channel_to_chanspec(struct ieee80211_channel *ch) 378u16 channel_to_chanspec(struct ieee80211_channel *ch)
385{ 379{
386 u16 chanspec; 380 u16 chanspec;
387 381
@@ -393,19 +387,92 @@ static u16 channel_to_chanspec(struct ieee80211_channel *ch)
393 else 387 else
394 chanspec |= WL_CHANSPEC_BAND_5G; 388 chanspec |= WL_CHANSPEC_BAND_5G;
395 389
396 if (ch->flags & IEEE80211_CHAN_NO_HT40) { 390 chanspec |= WL_CHANSPEC_BW_20;
397 chanspec |= WL_CHANSPEC_BW_20; 391 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
398 chanspec |= WL_CHANSPEC_CTL_SB_NONE; 392
399 } else {
400 chanspec |= WL_CHANSPEC_BW_40;
401 if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
402 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
403 else
404 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
405 }
406 return chanspec; 393 return chanspec;
407} 394}
408 395
396/* Traverse a string of 1-byte tag/1-byte length/variable-length value
397 * triples, returning a pointer to the substring whose first element
398 * matches tag
399 */
400struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
401{
402 struct brcmf_tlv *elt;
403 int totlen;
404
405 elt = (struct brcmf_tlv *)buf;
406 totlen = buflen;
407
408 /* find tagged parameter */
409 while (totlen >= TLV_HDR_LEN) {
410 int len = elt->len;
411
412 /* validate remaining totlen */
413 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
414 return elt;
415
416 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
417 totlen -= (len + TLV_HDR_LEN);
418 }
419
420 return NULL;
421}
422
423/* Is any of the tlvs the expected entry? If
424 * not update the tlvs buffer pointer/length.
425 */
426static bool
427brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
428 u8 *oui, u32 oui_len, u8 type)
429{
430 /* If the contents match the OUI and the type */
431 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
432 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
433 type == ie[TLV_BODY_OFF + oui_len]) {
434 return true;
435 }
436
437 if (tlvs == NULL)
438 return false;
439 /* point to the next ie */
440 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
441 /* calculate the length of the rest of the buffer */
442 *tlvs_len -= (int)(ie - *tlvs);
443 /* update the pointer to the start of the buffer */
444 *tlvs = ie;
445
446 return false;
447}
448
449static struct brcmf_vs_tlv *
450brcmf_find_wpaie(u8 *parse, u32 len)
451{
452 struct brcmf_tlv *ie;
453
454 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
455 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
456 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
457 return (struct brcmf_vs_tlv *)ie;
458 }
459 return NULL;
460}
461
462static struct brcmf_vs_tlv *
463brcmf_find_wpsie(u8 *parse, u32 len)
464{
465 struct brcmf_tlv *ie;
466
467 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
468 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
469 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
470 return (struct brcmf_vs_tlv *)ie;
471 }
472 return NULL;
473}
474
475
409static void convert_key_from_CPU(struct brcmf_wsec_key *key, 476static void convert_key_from_CPU(struct brcmf_wsec_key *key,
410 struct brcmf_wsec_key_le *key_le) 477 struct brcmf_wsec_key_le *key_le)
411{ 478{
@@ -438,11 +505,153 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
438 return err; 505 return err;
439} 506}
440 507
508static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
509 const char *name,
510 enum nl80211_iftype type,
511 u32 *flags,
512 struct vif_params *params)
513{
514 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
515 switch (type) {
516 case NL80211_IFTYPE_ADHOC:
517 case NL80211_IFTYPE_STATION:
518 case NL80211_IFTYPE_AP:
519 case NL80211_IFTYPE_AP_VLAN:
520 case NL80211_IFTYPE_WDS:
521 case NL80211_IFTYPE_MONITOR:
522 case NL80211_IFTYPE_MESH_POINT:
523 return ERR_PTR(-EOPNOTSUPP);
524 case NL80211_IFTYPE_P2P_CLIENT:
525 case NL80211_IFTYPE_P2P_GO:
526 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
527 case NL80211_IFTYPE_UNSPECIFIED:
528 case NL80211_IFTYPE_P2P_DEVICE:
529 default:
530 return ERR_PTR(-EINVAL);
531 }
532}
533
534void brcmf_set_mpc(struct net_device *ndev, int mpc)
535{
536 struct brcmf_if *ifp = netdev_priv(ndev);
537 s32 err = 0;
538
539 if (check_vif_up(ifp->vif)) {
540 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
541 if (err) {
542 brcmf_err("fail to set mpc\n");
543 return;
544 }
545 brcmf_dbg(INFO, "MPC : %d\n", mpc);
546 }
547}
548
549s32
550brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
551 struct net_device *ndev,
552 bool aborted, bool fw_abort)
553{
554 struct brcmf_scan_params_le params_le;
555 struct cfg80211_scan_request *scan_request;
556 s32 err = 0;
557
558 brcmf_dbg(SCAN, "Enter\n");
559
560 /* clear scan request, because the FW abort can cause a second call */
561 /* to this functon and might cause a double cfg80211_scan_done */
562 scan_request = cfg->scan_request;
563 cfg->scan_request = NULL;
564
565 if (timer_pending(&cfg->escan_timeout))
566 del_timer_sync(&cfg->escan_timeout);
567
568 if (fw_abort) {
569 /* Do a scan abort to stop the driver's scan engine */
570 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
571 memset(&params_le, 0, sizeof(params_le));
572 memset(params_le.bssid, 0xFF, ETH_ALEN);
573 params_le.bss_type = DOT11_BSSTYPE_ANY;
574 params_le.scan_type = 0;
575 params_le.channel_num = cpu_to_le32(1);
576 params_le.nprobes = cpu_to_le32(1);
577 params_le.active_time = cpu_to_le32(-1);
578 params_le.passive_time = cpu_to_le32(-1);
579 params_le.home_time = cpu_to_le32(-1);
580 /* Scan is aborted by setting channel_list[0] to -1 */
581 params_le.channel_list[0] = cpu_to_le16(-1);
582 /* E-Scan (or anyother type) can be aborted by SCAN */
583 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
584 &params_le, sizeof(params_le));
585 if (err)
586 brcmf_err("Scan abort failed\n");
587 }
588 /*
589 * e-scan can be initiated by scheduled scan
590 * which takes precedence.
591 */
592 if (cfg->sched_escan) {
593 brcmf_dbg(SCAN, "scheduled scan completed\n");
594 cfg->sched_escan = false;
595 if (!aborted)
596 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
597 brcmf_set_mpc(ndev, 1);
598 } else if (scan_request) {
599 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
600 aborted ? "Aborted" : "Done");
601 cfg80211_scan_done(scan_request, aborted);
602 brcmf_set_mpc(ndev, 1);
603 }
604 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
605 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
606
607 return err;
608}
609
610static
611int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
612{
613 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
614 struct net_device *ndev = wdev->netdev;
615
616 /* vif event pending in firmware */
617 if (brcmf_cfg80211_vif_event_armed(cfg))
618 return -EBUSY;
619
620 if (ndev) {
621 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
622 cfg->escan_info.ndev == ndev)
623 brcmf_notify_escan_complete(cfg, ndev, true,
624 true);
625
626 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
627 }
628
629 switch (wdev->iftype) {
630 case NL80211_IFTYPE_ADHOC:
631 case NL80211_IFTYPE_STATION:
632 case NL80211_IFTYPE_AP:
633 case NL80211_IFTYPE_AP_VLAN:
634 case NL80211_IFTYPE_WDS:
635 case NL80211_IFTYPE_MONITOR:
636 case NL80211_IFTYPE_MESH_POINT:
637 return -EOPNOTSUPP;
638 case NL80211_IFTYPE_P2P_CLIENT:
639 case NL80211_IFTYPE_P2P_GO:
640 return brcmf_p2p_del_vif(wiphy, wdev);
641 case NL80211_IFTYPE_UNSPECIFIED:
642 case NL80211_IFTYPE_P2P_DEVICE:
643 default:
644 return -EINVAL;
645 }
646 return -EOPNOTSUPP;
647}
648
441static s32 649static s32
442brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, 650brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
443 enum nl80211_iftype type, u32 *flags, 651 enum nl80211_iftype type, u32 *flags,
444 struct vif_params *params) 652 struct vif_params *params)
445{ 653{
654 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
446 struct brcmf_if *ifp = netdev_priv(ndev); 655 struct brcmf_if *ifp = netdev_priv(ndev);
447 struct brcmf_cfg80211_vif *vif = ifp->vif; 656 struct brcmf_cfg80211_vif *vif = ifp->vif;
448 s32 infra = 0; 657 s32 infra = 0;
@@ -462,10 +671,23 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
462 infra = 0; 671 infra = 0;
463 break; 672 break;
464 case NL80211_IFTYPE_STATION: 673 case NL80211_IFTYPE_STATION:
674 /* Ignore change for p2p IF. Unclear why supplicant does this */
675 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
676 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
677 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
678 /* WAR: It is unexpected to get a change of VIF for P2P
679 * IF, but it happens. The request can not be handled
680 * but returning EPERM causes a crash. Returning 0
681 * without setting ieee80211_ptr->iftype causes trace
682 * (WARN_ON) but it works with wpa_supplicant
683 */
684 return 0;
685 }
465 vif->mode = WL_MODE_BSS; 686 vif->mode = WL_MODE_BSS;
466 infra = 1; 687 infra = 1;
467 break; 688 break;
468 case NL80211_IFTYPE_AP: 689 case NL80211_IFTYPE_AP:
690 case NL80211_IFTYPE_P2P_GO:
469 vif->mode = WL_MODE_AP; 691 vif->mode = WL_MODE_AP;
470 ap = 1; 692 ap = 1;
471 break; 693 break;
@@ -475,8 +697,14 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
475 } 697 }
476 698
477 if (ap) { 699 if (ap) {
478 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state); 700 if (type == NL80211_IFTYPE_P2P_GO) {
479 brcmf_dbg(INFO, "IF Type = AP\n"); 701 brcmf_dbg(INFO, "IF Type = P2P GO\n");
702 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
703 }
704 if (!err) {
705 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
706 brcmf_dbg(INFO, "IF Type = AP\n");
707 }
480 } else { 708 } else {
481 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra); 709 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
482 if (err) { 710 if (err) {
@@ -495,21 +723,6 @@ done:
495 return err; 723 return err;
496} 724}
497 725
498static void brcmf_set_mpc(struct net_device *ndev, int mpc)
499{
500 struct brcmf_if *ifp = netdev_priv(ndev);
501 s32 err = 0;
502
503 if (check_vif_up(ifp->vif)) {
504 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
505 if (err) {
506 brcmf_err("fail to set mpc\n");
507 return;
508 }
509 brcmf_dbg(INFO, "MPC : %d\n", mpc);
510 }
511}
512
513static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, 726static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
514 struct cfg80211_scan_request *request) 727 struct cfg80211_scan_request *request)
515{ 728{
@@ -590,69 +803,6 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
590} 803}
591 804
592static s32 805static s32
593brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
594 struct net_device *ndev,
595 bool aborted, bool fw_abort)
596{
597 struct brcmf_scan_params_le params_le;
598 struct cfg80211_scan_request *scan_request;
599 s32 err = 0;
600
601 brcmf_dbg(SCAN, "Enter\n");
602
603 /* clear scan request, because the FW abort can cause a second call */
604 /* to this functon and might cause a double cfg80211_scan_done */
605 scan_request = cfg->scan_request;
606 cfg->scan_request = NULL;
607
608 if (timer_pending(&cfg->escan_timeout))
609 del_timer_sync(&cfg->escan_timeout);
610
611 if (fw_abort) {
612 /* Do a scan abort to stop the driver's scan engine */
613 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
614 memset(&params_le, 0, sizeof(params_le));
615 memset(params_le.bssid, 0xFF, ETH_ALEN);
616 params_le.bss_type = DOT11_BSSTYPE_ANY;
617 params_le.scan_type = 0;
618 params_le.channel_num = cpu_to_le32(1);
619 params_le.nprobes = cpu_to_le32(1);
620 params_le.active_time = cpu_to_le32(-1);
621 params_le.passive_time = cpu_to_le32(-1);
622 params_le.home_time = cpu_to_le32(-1);
623 /* Scan is aborted by setting channel_list[0] to -1 */
624 params_le.channel_list[0] = cpu_to_le16(-1);
625 /* E-Scan (or anyother type) can be aborted by SCAN */
626 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
627 &params_le, sizeof(params_le));
628 if (err)
629 brcmf_err("Scan abort failed\n");
630 }
631 /*
632 * e-scan can be initiated by scheduled scan
633 * which takes precedence.
634 */
635 if (cfg->sched_escan) {
636 brcmf_dbg(SCAN, "scheduled scan completed\n");
637 cfg->sched_escan = false;
638 if (!aborted)
639 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
640 brcmf_set_mpc(ndev, 1);
641 } else if (scan_request) {
642 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
643 aborted ? "Aborted" : "Done");
644 cfg80211_scan_done(scan_request, aborted);
645 brcmf_set_mpc(ndev, 1);
646 }
647 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
648 brcmf_err("Scan complete while device not scanning\n");
649 return -EPERM;
650 }
651
652 return err;
653}
654
655static s32
656brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, 806brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
657 struct cfg80211_scan_request *request, u16 action) 807 struct cfg80211_scan_request *request, u16 action)
658{ 808{
@@ -703,11 +853,12 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
703 s32 err; 853 s32 err;
704 u32 passive_scan; 854 u32 passive_scan;
705 struct brcmf_scan_results *results; 855 struct brcmf_scan_results *results;
856 struct escan_info *escan = &cfg->escan_info;
706 857
707 brcmf_dbg(SCAN, "Enter\n"); 858 brcmf_dbg(SCAN, "Enter\n");
708 cfg->escan_info.ndev = ndev; 859 escan->ndev = ndev;
709 cfg->escan_info.wiphy = wiphy; 860 escan->wiphy = wiphy;
710 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING; 861 escan->escan_state = WL_ESCAN_STATE_SCANNING;
711 passive_scan = cfg->active_scan ? 0 : 1; 862 passive_scan = cfg->active_scan ? 0 : 1;
712 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN, 863 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
713 passive_scan); 864 passive_scan);
@@ -721,7 +872,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
721 results->count = 0; 872 results->count = 0;
722 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE; 873 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
723 874
724 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START); 875 err = escan->run(cfg, ndev, request, WL_ESCAN_ACTION_START);
725 if (err) 876 if (err)
726 brcmf_set_mpc(ndev, 1); 877 brcmf_set_mpc(ndev, 1);
727 return err; 878 return err;
@@ -758,6 +909,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
758 return -EAGAIN; 909 return -EAGAIN;
759 } 910 }
760 911
912 /* If scan req comes for p2p0, send it over primary I/F */
913 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) {
914 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
915 ndev = ifp->ndev;
916 }
917
761 /* Arm scan timeout timer */ 918 /* Arm scan timeout timer */
762 mod_timer(&cfg->escan_timeout, jiffies + 919 mod_timer(&cfg->escan_timeout, jiffies +
763 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); 920 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
@@ -776,6 +933,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
776 cfg->scan_request = request; 933 cfg->scan_request = request;
777 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 934 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
778 if (escan_req) { 935 if (escan_req) {
936 cfg->escan_info.run = brcmf_run_escan;
937 err = brcmf_p2p_scan_prep(wiphy, request, ifp->vif);
938 if (err)
939 goto scan_out;
940
779 err = brcmf_do_escan(cfg, wiphy, ndev, request); 941 err = brcmf_do_escan(cfg, wiphy, ndev, request);
780 if (err) 942 if (err)
781 goto scan_out; 943 goto scan_out;
@@ -933,31 +1095,6 @@ static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
933 memset(prof, 0, sizeof(*prof)); 1095 memset(prof, 0, sizeof(*prof));
934} 1096}
935 1097
936static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
937 size_t *join_params_size)
938{
939 u16 chanspec = 0;
940
941 if (ch != 0) {
942 if (ch <= CH_MAX_2G_CHANNEL)
943 chanspec |= WL_CHANSPEC_BAND_2G;
944 else
945 chanspec |= WL_CHANSPEC_BAND_5G;
946
947 chanspec |= WL_CHANSPEC_BW_20;
948 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
949
950 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
951 sizeof(u16);
952
953 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
954 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
955 join_params->params_le.chanspec_num = cpu_to_le32(1);
956
957 brcmf_dbg(CONN, "channel %d, chanspec %#X\n", ch, chanspec);
958 }
959}
960
961static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) 1098static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
962{ 1099{
963 s32 err = 0; 1100 s32 err = 0;
@@ -988,6 +1125,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
988 s32 err = 0; 1125 s32 err = 0;
989 s32 wsec = 0; 1126 s32 wsec = 0;
990 s32 bcnprd; 1127 s32 bcnprd;
1128 u16 chanspec;
991 1129
992 brcmf_dbg(TRACE, "Enter\n"); 1130 brcmf_dbg(TRACE, "Enter\n");
993 if (!check_vif_up(ifp->vif)) 1131 if (!check_vif_up(ifp->vif))
@@ -1091,8 +1229,11 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1091 params->chandef.chan->center_freq); 1229 params->chandef.chan->center_freq);
1092 if (params->channel_fixed) { 1230 if (params->channel_fixed) {
1093 /* adding chanspec */ 1231 /* adding chanspec */
1094 brcmf_ch_to_chanspec(cfg->channel, 1232 chanspec = channel_to_chanspec(params->chandef.chan);
1095 &join_params, &join_params_size); 1233 join_params.params_le.chanspec_list[0] =
1234 cpu_to_le16(chanspec);
1235 join_params.params_le.chanspec_num = cpu_to_le32(1);
1236 join_params_size += sizeof(join_params.params_le);
1096 } 1237 }
1097 1238
1098 /* set channel for starter */ 1239 /* set channel for starter */
@@ -1155,7 +1296,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1155 else 1296 else
1156 val = WPA_AUTH_DISABLED; 1297 val = WPA_AUTH_DISABLED;
1157 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val); 1298 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1158 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val); 1299 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1159 if (err) { 1300 if (err) {
1160 brcmf_err("set wpa_auth failed (%d)\n", err); 1301 brcmf_err("set wpa_auth failed (%d)\n", err);
1161 return err; 1302 return err;
@@ -1194,7 +1335,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
1194 break; 1335 break;
1195 } 1336 }
1196 1337
1197 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val); 1338 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1198 if (err) { 1339 if (err) {
1199 brcmf_err("set auth failed (%d)\n", err); 1340 brcmf_err("set auth failed (%d)\n", err);
1200 return err; 1341 return err;
@@ -1258,7 +1399,12 @@ brcmf_set_set_cipher(struct net_device *ndev,
1258 } 1399 }
1259 1400
1260 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval); 1401 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1261 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval); 1402 /* In case of privacy, but no security and WPS then simulate */
1403 /* setting AES. WPS-2.0 allows no security */
1404 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1405 sme->privacy)
1406 pval = AES_ENABLED;
1407 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1262 if (err) { 1408 if (err) {
1263 brcmf_err("error (%d)\n", err); 1409 brcmf_err("error (%d)\n", err);
1264 return err; 1410 return err;
@@ -1280,8 +1426,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1280 s32 err = 0; 1426 s32 err = 0;
1281 1427
1282 if (sme->crypto.n_akm_suites) { 1428 if (sme->crypto.n_akm_suites) {
1283 err = brcmf_fil_iovar_int_get(netdev_priv(ndev), 1429 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1284 "wpa_auth", &val); 1430 "wpa_auth", &val);
1285 if (err) { 1431 if (err) {
1286 brcmf_err("could not get wpa_auth (%d)\n", err); 1432 brcmf_err("could not get wpa_auth (%d)\n", err);
1287 return err; 1433 return err;
@@ -1315,8 +1461,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1315 } 1461 }
1316 1462
1317 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); 1463 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1318 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), 1464 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1319 "wpa_auth", val); 1465 "wpa_auth", val);
1320 if (err) { 1466 if (err) {
1321 brcmf_err("could not set wpa_auth (%d)\n", err); 1467 brcmf_err("could not set wpa_auth (%d)\n", err);
1322 return err; 1468 return err;
@@ -1393,9 +1539,28 @@ brcmf_set_sharedkey(struct net_device *ndev,
1393 return err; 1539 return err;
1394} 1540}
1395 1541
1542static
1543enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1544 enum nl80211_auth_type type)
1545{
1546 u32 ci;
1547 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1548 /* shift to ignore chip revision */
1549 ci = brcmf_get_chip_info(ifp) >> 4;
1550 switch (ci) {
1551 case 43236:
1552 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1553 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1554 default:
1555 break;
1556 }
1557 }
1558 return type;
1559}
1560
1396static s32 1561static s32
1397brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, 1562brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1398 struct cfg80211_connect_params *sme) 1563 struct cfg80211_connect_params *sme)
1399{ 1564{
1400 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 1565 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1401 struct brcmf_if *ifp = netdev_priv(ndev); 1566 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -1403,7 +1568,12 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1403 struct ieee80211_channel *chan = sme->channel; 1568 struct ieee80211_channel *chan = sme->channel;
1404 struct brcmf_join_params join_params; 1569 struct brcmf_join_params join_params;
1405 size_t join_params_size; 1570 size_t join_params_size;
1406 struct brcmf_ssid ssid; 1571 struct brcmf_tlv *rsn_ie;
1572 struct brcmf_vs_tlv *wpa_ie;
1573 void *ie;
1574 u32 ie_len;
1575 struct brcmf_ext_join_params_le *ext_join_params;
1576 u16 chanspec;
1407 1577
1408 s32 err = 0; 1578 s32 err = 0;
1409 1579
@@ -1416,15 +1586,46 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1416 return -EOPNOTSUPP; 1586 return -EOPNOTSUPP;
1417 } 1587 }
1418 1588
1589 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1590 /* A normal (non P2P) connection request setup. */
1591 ie = NULL;
1592 ie_len = 0;
1593 /* find the WPA_IE */
1594 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1595 if (wpa_ie) {
1596 ie = wpa_ie;
1597 ie_len = wpa_ie->len + TLV_HDR_LEN;
1598 } else {
1599 /* find the RSN_IE */
1600 rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
1601 WLAN_EID_RSN);
1602 if (rsn_ie) {
1603 ie = rsn_ie;
1604 ie_len = rsn_ie->len + TLV_HDR_LEN;
1605 }
1606 }
1607 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1608 }
1609
1610 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1611 sme->ie, sme->ie_len);
1612 if (err)
1613 brcmf_err("Set Assoc REQ IE Failed\n");
1614 else
1615 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1616
1419 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); 1617 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1420 1618
1421 if (chan) { 1619 if (chan) {
1422 cfg->channel = 1620 cfg->channel =
1423 ieee80211_frequency_to_channel(chan->center_freq); 1621 ieee80211_frequency_to_channel(chan->center_freq);
1424 brcmf_dbg(CONN, "channel (%d), center_req (%d)\n", 1622 chanspec = channel_to_chanspec(chan);
1425 cfg->channel, chan->center_freq); 1623 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1426 } else 1624 cfg->channel, chan->center_freq, chanspec);
1625 } else {
1427 cfg->channel = 0; 1626 cfg->channel = 0;
1627 chanspec = 0;
1628 }
1428 1629
1429 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); 1630 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1430 1631
@@ -1434,6 +1635,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1434 goto done; 1635 goto done;
1435 } 1636 }
1436 1637
1638 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1437 err = brcmf_set_auth_type(ndev, sme); 1639 err = brcmf_set_auth_type(ndev, sme);
1438 if (err) { 1640 if (err) {
1439 brcmf_err("wl_set_auth_type failed (%d)\n", err); 1641 brcmf_err("wl_set_auth_type failed (%d)\n", err);
@@ -1458,27 +1660,88 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1458 goto done; 1660 goto done;
1459 } 1661 }
1460 1662
1663 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1664 (u32)sme->ssid_len);
1665 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1666 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1667 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1668 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1669 profile->ssid.SSID_len);
1670 }
1671
1672 /* Join with specific BSSID and cached SSID
1673 * If SSID is zero join based on BSSID only
1674 */
1675 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1676 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1677 if (cfg->channel)
1678 join_params_size += sizeof(u16);
1679 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1680 if (ext_join_params == NULL) {
1681 err = -ENOMEM;
1682 goto done;
1683 }
1684 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1685 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1686 profile->ssid.SSID_len);
1687 /*increase dwell time to receive probe response or detect Beacon
1688 * from target AP at a noisy air only during connect command
1689 */
1690 ext_join_params->scan_le.active_time =
1691 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1692 ext_join_params->scan_le.passive_time =
1693 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1694 /* Set up join scan parameters */
1695 ext_join_params->scan_le.scan_type = -1;
1696 /* to sync with presence period of VSDB GO.
1697 * Send probe request more frequently. Probe request will be stopped
1698 * when it gets probe response from target AP/GO.
1699 */
1700 ext_join_params->scan_le.nprobes =
1701 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1702 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1703 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1704
1705 if (sme->bssid)
1706 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1707 else
1708 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1709
1710 if (cfg->channel) {
1711 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1712
1713 ext_join_params->assoc_le.chanspec_list[0] =
1714 cpu_to_le16(chanspec);
1715 }
1716
1717 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1718 join_params_size);
1719 kfree(ext_join_params);
1720 if (!err)
1721 /* This is it. join command worked, we are done */
1722 goto done;
1723
1724 /* join command failed, fallback to set ssid */
1461 memset(&join_params, 0, sizeof(join_params)); 1725 memset(&join_params, 0, sizeof(join_params));
1462 join_params_size = sizeof(join_params.ssid_le); 1726 join_params_size = sizeof(join_params.ssid_le);
1463 1727
1464 profile->ssid.SSID_len = min_t(u32,
1465 sizeof(ssid.SSID), (u32)sme->ssid_len);
1466 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len); 1728 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1467 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1468 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len); 1729 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1469 1730
1470 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN); 1731 if (sme->bssid)
1471 1732 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1472 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) 1733 else
1473 brcmf_dbg(CONN, "ssid \"%s\", len (%d)\n", 1734 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1474 ssid.SSID, ssid.SSID_len);
1475 1735
1476 brcmf_ch_to_chanspec(cfg->channel, 1736 if (cfg->channel) {
1477 &join_params, &join_params_size); 1737 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1738 join_params.params_le.chanspec_num = cpu_to_le32(1);
1739 join_params_size += sizeof(join_params.params_le);
1740 }
1478 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, 1741 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1479 &join_params, join_params_size); 1742 &join_params, join_params_size);
1480 if (err) 1743 if (err)
1481 brcmf_err("WLC_SET_SSID failed (%d)\n", err); 1744 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1482 1745
1483done: 1746done:
1484 if (err) 1747 if (err)
@@ -1937,7 +2200,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1937 goto done; 2200 goto done;
1938 } 2201 }
1939 /* Report the current tx rate */ 2202 /* Report the current tx rate */
1940 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); 2203 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1941 if (err) { 2204 if (err) {
1942 brcmf_err("Could not get rate (%d)\n", err); 2205 brcmf_err("Could not get rate (%d)\n", err);
1943 goto done; 2206 goto done;
@@ -2060,7 +2323,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2060 if (!bss) 2323 if (!bss)
2061 return -ENOMEM; 2324 return -ENOMEM;
2062 2325
2063 cfg80211_put_bss(bss); 2326 cfg80211_put_bss(wiphy, bss);
2064 2327
2065 return err; 2328 return err;
2066} 2329}
@@ -2166,7 +2429,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2166 goto CleanUp; 2429 goto CleanUp;
2167 } 2430 }
2168 2431
2169 cfg80211_put_bss(bss); 2432 cfg80211_put_bss(wiphy, bss);
2170 2433
2171CleanUp: 2434CleanUp:
2172 2435
@@ -2182,78 +2445,10 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2182 return vif->mode == WL_MODE_IBSS; 2445 return vif->mode == WL_MODE_IBSS;
2183} 2446}
2184 2447
2185/* 2448static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2186 * Traverse a string of 1-byte tag/1-byte length/variable-length value 2449 struct brcmf_if *ifp)
2187 * triples, returning a pointer to the substring whose first element
2188 * matches tag
2189 */
2190static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2191{
2192 struct brcmf_tlv *elt;
2193 int totlen;
2194
2195 elt = (struct brcmf_tlv *) buf;
2196 totlen = buflen;
2197
2198 /* find tagged parameter */
2199 while (totlen >= TLV_HDR_LEN) {
2200 int len = elt->len;
2201
2202 /* validate remaining totlen */
2203 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2204 return elt;
2205
2206 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2207 totlen -= (len + TLV_HDR_LEN);
2208 }
2209
2210 return NULL;
2211}
2212
2213/* Is any of the tlvs the expected entry? If
2214 * not update the tlvs buffer pointer/length.
2215 */
2216static bool
2217brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2218 u8 *oui, u32 oui_len, u8 type)
2219{
2220 /* If the contents match the OUI and the type */
2221 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2222 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2223 type == ie[TLV_BODY_OFF + oui_len]) {
2224 return true;
2225 }
2226
2227 if (tlvs == NULL)
2228 return false;
2229 /* point to the next ie */
2230 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2231 /* calculate the length of the rest of the buffer */
2232 *tlvs_len -= (int)(ie - *tlvs);
2233 /* update the pointer to the start of the buffer */
2234 *tlvs = ie;
2235
2236 return false;
2237}
2238
2239static struct brcmf_vs_tlv *
2240brcmf_find_wpaie(u8 *parse, u32 len)
2241{ 2450{
2242 struct brcmf_tlv *ie; 2451 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2243
2244 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2245 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2246 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2247 return (struct brcmf_vs_tlv *)ie;
2248 }
2249 return NULL;
2250}
2251
2252static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2253{
2254 struct net_device *ndev = cfg_to_ndev(cfg);
2255 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2256 struct brcmf_if *ifp = netdev_priv(ndev);
2257 struct brcmf_bss_info_le *bi; 2452 struct brcmf_bss_info_le *bi;
2258 struct brcmf_ssid *ssid; 2453 struct brcmf_ssid *ssid;
2259 struct brcmf_tlv *tim; 2454 struct brcmf_tlv *tim;
@@ -2309,7 +2504,7 @@ update_bss_info_out:
2309 return err; 2504 return err;
2310} 2505}
2311 2506
2312static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) 2507void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2313{ 2508{
2314 struct escan_info *escan = &cfg->escan_info; 2509 struct escan_info *escan = &cfg->escan_info;
2315 2510
@@ -2328,8 +2523,7 @@ static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2328 container_of(work, struct brcmf_cfg80211_info, 2523 container_of(work, struct brcmf_cfg80211_info,
2329 escan_timeout_work); 2524 escan_timeout_work);
2330 2525
2331 brcmf_notify_escan_complete(cfg, 2526 brcmf_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true);
2332 cfg->escan_info.ndev, true, true);
2333} 2527}
2334 2528
2335static void brcmf_escan_timeout(unsigned long data) 2529static void brcmf_escan_timeout(unsigned long data)
@@ -2406,11 +2600,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2406 brcmf_err("Invalid escan result (NULL pointer)\n"); 2600 brcmf_err("Invalid escan result (NULL pointer)\n");
2407 goto exit; 2601 goto exit;
2408 } 2602 }
2409 if (!cfg->scan_request) {
2410 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2411 goto exit;
2412 }
2413
2414 if (le16_to_cpu(escan_result_le->bss_count) != 1) { 2603 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2415 brcmf_err("Invalid bss_count %d: ignoring\n", 2604 brcmf_err("Invalid bss_count %d: ignoring\n",
2416 escan_result_le->bss_count); 2605 escan_result_le->bss_count);
@@ -2418,6 +2607,14 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2418 } 2607 }
2419 bss_info_le = &escan_result_le->bss_info_le; 2608 bss_info_le = &escan_result_le->bss_info_le;
2420 2609
2610 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2611 goto exit;
2612
2613 if (!cfg->scan_request) {
2614 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2615 goto exit;
2616 }
2617
2421 bi_length = le32_to_cpu(bss_info_le->length); 2618 bi_length = le32_to_cpu(bss_info_le->length);
2422 if (bi_length != (le32_to_cpu(escan_result_le->buflen) - 2619 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2423 WL_ESCAN_RESULTS_FIXED_SIZE)) { 2620 WL_ESCAN_RESULTS_FIXED_SIZE)) {
@@ -2456,6 +2653,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2456 list->count++; 2653 list->count++;
2457 } else { 2654 } else {
2458 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; 2655 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2656 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2657 goto exit;
2459 if (cfg->scan_request) { 2658 if (cfg->scan_request) {
2460 cfg->bss_list = (struct brcmf_scan_results *) 2659 cfg->bss_list = (struct brcmf_scan_results *)
2461 cfg->escan_info.escan_buf; 2660 cfg->escan_info.escan_buf;
@@ -2464,7 +2663,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2464 brcmf_notify_escan_complete(cfg, ndev, aborted, 2663 brcmf_notify_escan_complete(cfg, ndev, aborted,
2465 false); 2664 false);
2466 } else 2665 } else
2467 brcmf_err("Unexpected scan result 0x%x\n", status); 2666 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2667 status);
2468 } 2668 }
2469exit: 2669exit:
2470 return err; 2670 return err;
@@ -2968,9 +3168,8 @@ static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
2968} 3168}
2969#endif 3169#endif
2970 3170
2971static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx) 3171static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
2972{ 3172{
2973 struct brcmf_if *ifp = netdev_priv(ndev);
2974 s32 err; 3173 s32 err;
2975 3174
2976 /* set auth */ 3175 /* set auth */
@@ -3229,7 +3428,7 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3229 parsed_info->vndrie.oui[2], 3428 parsed_info->vndrie.oui[2],
3230 parsed_info->vndrie.oui_type); 3429 parsed_info->vndrie.oui_type);
3231 3430
3232 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER) 3431 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3233 break; 3432 break;
3234next: 3433next:
3235 remaining_len -= (ie->len + TLV_HDR_LEN); 3434 remaining_len -= (ie->len + TLV_HDR_LEN);
@@ -3263,7 +3462,6 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3263 return ie_len + VNDR_IE_HDR_SIZE; 3462 return ie_len + VNDR_IE_HDR_SIZE;
3264} 3463}
3265 3464
3266static
3267s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, 3465s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3268 const u8 *vndr_ie_buf, u32 vndr_ie_len) 3466 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3269{ 3467{
@@ -3295,24 +3493,28 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3295 if (!iovar_ie_buf) 3493 if (!iovar_ie_buf)
3296 return -ENOMEM; 3494 return -ENOMEM;
3297 curr_ie_buf = iovar_ie_buf; 3495 curr_ie_buf = iovar_ie_buf;
3298 if (ifp->vif->mode == WL_MODE_AP) { 3496 switch (pktflag) {
3299 switch (pktflag) { 3497 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3300 case VNDR_IE_PRBRSP_FLAG: 3498 mgmt_ie_buf = saved_ie->probe_req_ie;
3301 mgmt_ie_buf = saved_ie->probe_res_ie; 3499 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3302 mgmt_ie_len = &saved_ie->probe_res_ie_len; 3500 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3303 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie); 3501 break;
3304 break; 3502 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3305 case VNDR_IE_BEACON_FLAG: 3503 mgmt_ie_buf = saved_ie->probe_res_ie;
3306 mgmt_ie_buf = saved_ie->beacon_ie; 3504 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3307 mgmt_ie_len = &saved_ie->beacon_ie_len; 3505 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3308 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie); 3506 break;
3309 break; 3507 case BRCMF_VNDR_IE_BEACON_FLAG:
3310 default: 3508 mgmt_ie_buf = saved_ie->beacon_ie;
3311 err = -EPERM; 3509 mgmt_ie_len = &saved_ie->beacon_ie_len;
3312 brcmf_err("not suitable type\n"); 3510 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3313 goto exit; 3511 break;
3314 } 3512 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3315 } else { 3513 mgmt_ie_buf = saved_ie->assoc_req_ie;
3514 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3515 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3516 break;
3517 default:
3316 err = -EPERM; 3518 err = -EPERM;
3317 brcmf_err("not suitable type\n"); 3519 brcmf_err("not suitable type\n");
3318 goto exit; 3520 goto exit;
@@ -3421,6 +3623,49 @@ exit:
3421 return err; 3623 return err;
3422} 3624}
3423 3625
3626s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3627{
3628 s32 pktflags[] = {
3629 BRCMF_VNDR_IE_PRBREQ_FLAG,
3630 BRCMF_VNDR_IE_PRBRSP_FLAG,
3631 BRCMF_VNDR_IE_BEACON_FLAG
3632 };
3633 int i;
3634
3635 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3636 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3637
3638 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3639 return 0;
3640}
3641
3642static s32
3643brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3644 struct cfg80211_beacon_data *beacon)
3645{
3646 s32 err;
3647
3648 /* Set Beacon IEs to FW */
3649 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3650 beacon->tail, beacon->tail_len);
3651 if (err) {
3652 brcmf_err("Set Beacon IE Failed\n");
3653 return err;
3654 }
3655 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3656
3657 /* Set Probe Response IEs to FW */
3658 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3659 beacon->proberesp_ies,
3660 beacon->proberesp_ies_len);
3661 if (err)
3662 brcmf_err("Set Probe Resp IE Failed\n");
3663 else
3664 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3665
3666 return err;
3667}
3668
3424static s32 3669static s32
3425brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, 3670brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3426 struct cfg80211_ap_settings *settings) 3671 struct cfg80211_ap_settings *settings)
@@ -3433,7 +3678,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3433 struct brcmf_tlv *rsn_ie; 3678 struct brcmf_tlv *rsn_ie;
3434 struct brcmf_vs_tlv *wpa_ie; 3679 struct brcmf_vs_tlv *wpa_ie;
3435 struct brcmf_join_params join_params; 3680 struct brcmf_join_params join_params;
3436 s32 bssidx = 0; 3681 enum nl80211_iftype dev_role;
3682 struct brcmf_fil_bss_enable_le bss_enable;
3437 3683
3438 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", 3684 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3439 cfg80211_get_chandef_type(&settings->chandef), 3685 cfg80211_get_chandef_type(&settings->chandef),
@@ -3443,10 +3689,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3443 settings->ssid, settings->ssid_len, settings->auth_type, 3689 settings->ssid, settings->ssid_len, settings->auth_type,
3444 settings->inactivity_timeout); 3690 settings->inactivity_timeout);
3445 3691
3446 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) { 3692 dev_role = ifp->vif->wdev.iftype;
3447 brcmf_err("Not in AP creation mode\n");
3448 return -EPERM;
3449 }
3450 3693
3451 memset(&ssid_le, 0, sizeof(ssid_le)); 3694 memset(&ssid_le, 0, sizeof(ssid_le));
3452 if (settings->ssid == NULL || settings->ssid_len == 0) { 3695 if (settings->ssid == NULL || settings->ssid_len == 0) {
@@ -3467,21 +3710,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3467 } 3710 }
3468 3711
3469 brcmf_set_mpc(ndev, 0); 3712 brcmf_set_mpc(ndev, 0);
3470 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3471 if (err < 0) {
3472 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3473 goto exit;
3474 }
3475 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3476 if (err < 0) {
3477 brcmf_err("SET INFRA error %d\n", err);
3478 goto exit;
3479 }
3480 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3481 if (err < 0) {
3482 brcmf_err("setting AP mode failed %d\n", err);
3483 goto exit;
3484 }
3485 3713
3486 /* find the RSN_IE */ 3714 /* find the RSN_IE */
3487 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, 3715 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3507,27 +3735,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3507 } 3735 }
3508 } else { 3736 } else {
3509 brcmf_dbg(TRACE, "No WPA(2) IEs found\n"); 3737 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3510 brcmf_configure_opensecurity(ndev, bssidx); 3738 brcmf_configure_opensecurity(ifp);
3511 } 3739 }
3512 /* Set Beacon IEs to FW */
3513 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3514 VNDR_IE_BEACON_FLAG,
3515 settings->beacon.tail,
3516 settings->beacon.tail_len);
3517 if (err)
3518 brcmf_err("Set Beacon IE Failed\n");
3519 else
3520 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3521 3740
3522 /* Set Probe Response IEs to FW */ 3741 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3523 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3524 VNDR_IE_PRBRSP_FLAG,
3525 settings->beacon.proberesp_ies,
3526 settings->beacon.proberesp_ies_len);
3527 if (err)
3528 brcmf_err("Set Probe Resp IE Failed\n");
3529 else
3530 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3531 3742
3532 if (settings->beacon_interval) { 3743 if (settings->beacon_interval) {
3533 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, 3744 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
@@ -3545,22 +3756,62 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3545 goto exit; 3756 goto exit;
3546 } 3757 }
3547 } 3758 }
3548 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); 3759
3549 if (err < 0) { 3760 if (dev_role == NL80211_IFTYPE_AP) {
3550 brcmf_err("BRCMF_C_UP error (%d)\n", err); 3761 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3551 goto exit; 3762 if (err < 0) {
3763 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3764 goto exit;
3765 }
3766 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3552 } 3767 }
3553 3768
3554 memset(&join_params, 0, sizeof(join_params)); 3769 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3555 /* join parameters starts with ssid */
3556 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3557 /* create softap */
3558 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3559 &join_params, sizeof(join_params));
3560 if (err < 0) { 3770 if (err < 0) {
3561 brcmf_err("SET SSID error (%d)\n", err); 3771 brcmf_err("SET INFRA error %d\n", err);
3562 goto exit; 3772 goto exit;
3563 } 3773 }
3774 if (dev_role == NL80211_IFTYPE_AP) {
3775 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3776 if (err < 0) {
3777 brcmf_err("setting AP mode failed %d\n", err);
3778 goto exit;
3779 }
3780 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3781 if (err < 0) {
3782 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3783 goto exit;
3784 }
3785
3786 memset(&join_params, 0, sizeof(join_params));
3787 /* join parameters starts with ssid */
3788 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3789 /* create softap */
3790 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3791 &join_params, sizeof(join_params));
3792 if (err < 0) {
3793 brcmf_err("SET SSID error (%d)\n", err);
3794 goto exit;
3795 }
3796 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3797 } else {
3798 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3799 sizeof(ssid_le));
3800 if (err < 0) {
3801 brcmf_err("setting ssid failed %d\n", err);
3802 goto exit;
3803 }
3804 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3805 bss_enable.enable = cpu_to_le32(1);
3806 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3807 sizeof(bss_enable));
3808 if (err < 0) {
3809 brcmf_err("bss_enable config failed %d\n", err);
3810 goto exit;
3811 }
3812
3813 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3814 }
3564 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 3815 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3565 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 3816 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3566 3817
@@ -3574,10 +3825,11 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3574{ 3825{
3575 struct brcmf_if *ifp = netdev_priv(ndev); 3826 struct brcmf_if *ifp = netdev_priv(ndev);
3576 s32 err = -EPERM; 3827 s32 err = -EPERM;
3828 struct brcmf_fil_bss_enable_le bss_enable;
3577 3829
3578 brcmf_dbg(TRACE, "Enter\n"); 3830 brcmf_dbg(TRACE, "Enter\n");
3579 3831
3580 if (ifp->vif->mode == WL_MODE_AP) { 3832 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3581 /* Due to most likely deauths outstanding we sleep */ 3833 /* Due to most likely deauths outstanding we sleep */
3582 /* first to make sure they get processed by fw. */ 3834 /* first to make sure they get processed by fw. */
3583 msleep(400); 3835 msleep(400);
@@ -3591,18 +3843,41 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3591 brcmf_err("BRCMF_C_UP error %d\n", err); 3843 brcmf_err("BRCMF_C_UP error %d\n", err);
3592 goto exit; 3844 goto exit;
3593 } 3845 }
3594 brcmf_set_mpc(ndev, 1); 3846 } else {
3595 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 3847 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3596 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 3848 bss_enable.enable = cpu_to_le32(0);
3849 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3850 sizeof(bss_enable));
3851 if (err < 0)
3852 brcmf_err("bss_enable config failed %d\n", err);
3597 } 3853 }
3854 brcmf_set_mpc(ndev, 1);
3855 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3856 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3857
3598exit: 3858exit:
3599 return err; 3859 return err;
3600} 3860}
3601 3861
3862static s32
3863brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3864 struct cfg80211_beacon_data *info)
3865{
3866 struct brcmf_if *ifp = netdev_priv(ndev);
3867 s32 err;
3868
3869 brcmf_dbg(TRACE, "Enter\n");
3870
3871 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3872
3873 return err;
3874}
3875
3602static int 3876static int
3603brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, 3877brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3604 u8 *mac) 3878 u8 *mac)
3605{ 3879{
3880 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3606 struct brcmf_scb_val_le scbval; 3881 struct brcmf_scb_val_le scbval;
3607 struct brcmf_if *ifp = netdev_priv(ndev); 3882 struct brcmf_if *ifp = netdev_priv(ndev);
3608 s32 err; 3883 s32 err;
@@ -3612,6 +3887,8 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3612 3887
3613 brcmf_dbg(TRACE, "Enter %pM\n", mac); 3888 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3614 3889
3890 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3891 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3615 if (!check_vif_up(ifp->vif)) 3892 if (!check_vif_up(ifp->vif))
3616 return -EIO; 3893 return -EIO;
3617 3894
@@ -3626,7 +3903,147 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3626 return err; 3903 return err;
3627} 3904}
3628 3905
3906
3907static void
3908brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3909 struct wireless_dev *wdev,
3910 u16 frame_type, bool reg)
3911{
3912 struct brcmf_if *ifp = netdev_priv(wdev->netdev);
3913 struct brcmf_cfg80211_vif *vif = ifp->vif;
3914 u16 mgmt_type;
3915
3916 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3917
3918 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3919 if (reg)
3920 vif->mgmt_rx_reg |= BIT(mgmt_type);
3921 else
3922 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3923}
3924
3925
3926static int
3927brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3928 struct ieee80211_channel *chan, bool offchan,
3929 unsigned int wait, const u8 *buf, size_t len,
3930 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3931{
3932 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3933 const struct ieee80211_mgmt *mgmt;
3934 struct brcmf_if *ifp;
3935 struct brcmf_cfg80211_vif *vif;
3936 s32 err = 0;
3937 s32 ie_offset;
3938 s32 ie_len;
3939 struct brcmf_fil_action_frame_le *action_frame;
3940 struct brcmf_fil_af_params_le *af_params;
3941 bool ack;
3942 s32 chan_nr;
3943
3944 brcmf_dbg(TRACE, "Enter\n");
3945
3946 *cookie = 0;
3947
3948 mgmt = (const struct ieee80211_mgmt *)buf;
3949
3950 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3951 brcmf_err("Driver only allows MGMT packet type\n");
3952 return -EPERM;
3953 }
3954
3955 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3956 /* Right now the only reason to get a probe response */
3957 /* is for p2p listen response or for p2p GO from */
3958 /* wpa_supplicant. Unfortunately the probe is send */
3959 /* on primary ndev, while dongle wants it on the p2p */
3960 /* vif. Since this is only reason for a probe */
3961 /* response to be sent, the vif is taken from cfg. */
3962 /* If ever desired to send proberesp for non p2p */
3963 /* response then data should be checked for */
3964 /* "DIRECT-". Note in future supplicant will take */
3965 /* dedicated p2p wdev to do this and then this 'hack'*/
3966 /* is not needed anymore. */
3967 ie_offset = DOT11_MGMT_HDR_LEN +
3968 DOT11_BCN_PRB_FIXED_LEN;
3969 ie_len = len - ie_offset;
3970 ifp = netdev_priv(wdev->netdev);
3971 vif = ifp->vif;
3972 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
3973 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
3974 err = brcmf_vif_set_mgmt_ie(vif,
3975 BRCMF_VNDR_IE_PRBRSP_FLAG,
3976 &buf[ie_offset],
3977 ie_len);
3978 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
3979 GFP_KERNEL);
3980 } else if (ieee80211_is_action(mgmt->frame_control)) {
3981 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
3982 if (af_params == NULL) {
3983 brcmf_err("unable to allocate frame\n");
3984 err = -ENOMEM;
3985 goto exit;
3986 }
3987 action_frame = &af_params->action_frame;
3988 /* Add the packet Id */
3989 action_frame->packet_id = cpu_to_le32(*cookie);
3990 /* Add BSSID */
3991 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
3992 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
3993 /* Add the length exepted for 802.11 header */
3994 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
3995 /* Add the channel */
3996 chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
3997 af_params->channel = cpu_to_le32(chan_nr);
3998
3999 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4000 le16_to_cpu(action_frame->len));
4001
4002 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4003 *cookie, le16_to_cpu(action_frame->len),
4004 chan->center_freq);
4005
4006 ack = brcmf_p2p_send_action_frame(cfg, wdev->netdev,
4007 af_params);
4008
4009 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4010 GFP_KERNEL);
4011 kfree(af_params);
4012 } else {
4013 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4014 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4015 }
4016
4017exit:
4018 return err;
4019}
4020
4021
4022static int
4023brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4024 struct wireless_dev *wdev,
4025 u64 cookie)
4026{
4027 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4028 struct brcmf_cfg80211_vif *vif;
4029 int err = 0;
4030
4031 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4032
4033 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4034 if (vif == NULL) {
4035 brcmf_err("No p2p device available for probe response\n");
4036 err = -ENODEV;
4037 goto exit;
4038 }
4039 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4040exit:
4041 return err;
4042}
4043
3629static struct cfg80211_ops wl_cfg80211_ops = { 4044static struct cfg80211_ops wl_cfg80211_ops = {
4045 .add_virtual_intf = brcmf_cfg80211_add_iface,
4046 .del_virtual_intf = brcmf_cfg80211_del_iface,
3630 .change_virtual_intf = brcmf_cfg80211_change_iface, 4047 .change_virtual_intf = brcmf_cfg80211_change_iface,
3631 .scan = brcmf_cfg80211_scan, 4048 .scan = brcmf_cfg80211_scan,
3632 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params, 4049 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
@@ -3650,28 +4067,43 @@ static struct cfg80211_ops wl_cfg80211_ops = {
3650 .flush_pmksa = brcmf_cfg80211_flush_pmksa, 4067 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3651 .start_ap = brcmf_cfg80211_start_ap, 4068 .start_ap = brcmf_cfg80211_start_ap,
3652 .stop_ap = brcmf_cfg80211_stop_ap, 4069 .stop_ap = brcmf_cfg80211_stop_ap,
4070 .change_beacon = brcmf_cfg80211_change_beacon,
3653 .del_station = brcmf_cfg80211_del_station, 4071 .del_station = brcmf_cfg80211_del_station,
3654 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 4072 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3655 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, 4073 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4074 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4075 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4076 .remain_on_channel = brcmf_p2p_remain_on_channel,
4077 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
3656#ifdef CONFIG_NL80211_TESTMODE 4078#ifdef CONFIG_NL80211_TESTMODE
3657 .testmode_cmd = brcmf_cfg80211_testmode 4079 .testmode_cmd = brcmf_cfg80211_testmode
3658#endif 4080#endif
3659}; 4081};
3660 4082
3661static s32 brcmf_mode_to_nl80211_iftype(s32 mode) 4083static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
3662{ 4084{
3663 s32 err = 0; 4085 switch (type) {
3664 4086 case NL80211_IFTYPE_AP_VLAN:
3665 switch (mode) { 4087 case NL80211_IFTYPE_WDS:
3666 case WL_MODE_BSS: 4088 case NL80211_IFTYPE_MONITOR:
3667 return NL80211_IFTYPE_STATION; 4089 case NL80211_IFTYPE_MESH_POINT:
3668 case WL_MODE_IBSS: 4090 return -ENOTSUPP;
3669 return NL80211_IFTYPE_ADHOC; 4091 case NL80211_IFTYPE_ADHOC:
4092 return WL_MODE_IBSS;
4093 case NL80211_IFTYPE_STATION:
4094 case NL80211_IFTYPE_P2P_CLIENT:
4095 return WL_MODE_BSS;
4096 case NL80211_IFTYPE_AP:
4097 case NL80211_IFTYPE_P2P_GO:
4098 return WL_MODE_AP;
4099 case NL80211_IFTYPE_P2P_DEVICE:
4100 return WL_MODE_P2P;
4101 case NL80211_IFTYPE_UNSPECIFIED:
3670 default: 4102 default:
3671 return NL80211_IFTYPE_UNSPECIFIED; 4103 break;
3672 } 4104 }
3673 4105
3674 return err; 4106 return -EINVAL;
3675} 4107}
3676 4108
3677static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 4109static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
@@ -3683,6 +4115,56 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3683 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 4115 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3684} 4116}
3685 4117
4118static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4119 {
4120 .max = 2,
4121 .types = BIT(NL80211_IFTYPE_STATION) |
4122 BIT(NL80211_IFTYPE_ADHOC) |
4123 BIT(NL80211_IFTYPE_AP)
4124 },
4125 {
4126 .max = 1,
4127 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4128 },
4129 {
4130 .max = 1,
4131 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4132 BIT(NL80211_IFTYPE_P2P_GO)
4133 },
4134};
4135static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4136 {
4137 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4138 .num_different_channels = 1, /* no multi-channel for now */
4139 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4140 .limits = brcmf_iface_limits
4141 }
4142};
4143
4144static const struct ieee80211_txrx_stypes
4145brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4146 [NL80211_IFTYPE_STATION] = {
4147 .tx = 0xffff,
4148 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4149 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4150 },
4151 [NL80211_IFTYPE_P2P_CLIENT] = {
4152 .tx = 0xffff,
4153 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4154 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4155 },
4156 [NL80211_IFTYPE_P2P_GO] = {
4157 .tx = 0xffff,
4158 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4159 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4160 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4161 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4162 BIT(IEEE80211_STYPE_AUTH >> 4) |
4163 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4164 BIT(IEEE80211_STYPE_ACTION >> 4)
4165 }
4166};
4167
3686static struct wiphy *brcmf_setup_wiphy(struct device *phydev) 4168static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3687{ 4169{
3688 struct wiphy *wiphy; 4170 struct wiphy *wiphy;
@@ -3695,10 +4177,16 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3695 } 4177 }
3696 set_wiphy_dev(wiphy, phydev); 4178 set_wiphy_dev(wiphy, phydev);
3697 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 4179 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4180 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3698 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 4181 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3699 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 4182 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3700 BIT(NL80211_IFTYPE_ADHOC) | 4183 BIT(NL80211_IFTYPE_ADHOC) |
3701 BIT(NL80211_IFTYPE_AP); 4184 BIT(NL80211_IFTYPE_AP) |
4185 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4186 BIT(NL80211_IFTYPE_P2P_GO) |
4187 BIT(NL80211_IFTYPE_P2P_DEVICE);
4188 wiphy->iface_combinations = brcmf_iface_combos;
4189 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
3702 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 4190 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3703 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set 4191 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3704 * it as 11a by default. 4192 * it as 11a by default.
@@ -3710,10 +4198,11 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3710 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 4198 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3711 wiphy->cipher_suites = __wl_cipher_suites; 4199 wiphy->cipher_suites = __wl_cipher_suites;
3712 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 4200 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3713 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power 4201 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
3714 * save mode 4202 WIPHY_FLAG_OFFCHAN_TX |
3715 * by default 4203 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3716 */ 4204 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4205 wiphy->max_remain_on_channel_duration = 5000;
3717 brcmf_wiphy_pno_params(wiphy); 4206 brcmf_wiphy_pno_params(wiphy);
3718 err = wiphy_register(wiphy); 4207 err = wiphy_register(wiphy);
3719 if (err < 0) { 4208 if (err < 0) {
@@ -3724,31 +4213,25 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3724 return wiphy; 4213 return wiphy;
3725} 4214}
3726 4215
3727static
3728struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, 4216struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3729 struct net_device *netdev, 4217 enum nl80211_iftype type,
3730 s32 mode, bool pm_block) 4218 bool pm_block)
3731{ 4219{
3732 struct brcmf_cfg80211_vif *vif; 4220 struct brcmf_cfg80211_vif *vif;
3733 4221
3734 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT) 4222 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3735 return ERR_PTR(-ENOSPC); 4223 return ERR_PTR(-ENOSPC);
3736 4224
4225 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4226 sizeof(*vif));
3737 vif = kzalloc(sizeof(*vif), GFP_KERNEL); 4227 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3738 if (!vif) 4228 if (!vif)
3739 return ERR_PTR(-ENOMEM); 4229 return ERR_PTR(-ENOMEM);
3740 4230
3741 vif->wdev.wiphy = cfg->wiphy; 4231 vif->wdev.wiphy = cfg->wiphy;
3742 vif->wdev.netdev = netdev; 4232 vif->wdev.iftype = type;
3743 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3744
3745 if (netdev) {
3746 vif->ifp = netdev_priv(netdev);
3747 netdev->ieee80211_ptr = &vif->wdev;
3748 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3749 }
3750 4233
3751 vif->mode = mode; 4234 vif->mode = brcmf_nl80211_iftype_to_mode(type);
3752 vif->pm_block = pm_block; 4235 vif->pm_block = pm_block;
3753 vif->roam_off = -1; 4236 vif->roam_off = -1;
3754 4237
@@ -3759,7 +4242,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3759 return vif; 4242 return vif;
3760} 4243}
3761 4244
3762static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) 4245void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3763{ 4246{
3764 struct brcmf_cfg80211_info *cfg; 4247 struct brcmf_cfg80211_info *cfg;
3765 struct wiphy *wiphy; 4248 struct wiphy *wiphy;
@@ -3833,9 +4316,9 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3833 conn_info->resp_ie_len = 0; 4316 conn_info->resp_ie_len = 0;
3834} 4317}
3835 4318
3836static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) 4319static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4320 struct brcmf_if *ifp)
3837{ 4321{
3838 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3839 struct brcmf_cfg80211_assoc_ielen_le *assoc_info; 4322 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3840 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); 4323 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3841 u32 req_len; 4324 u32 req_len;
@@ -3911,9 +4394,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3911 4394
3912 brcmf_dbg(TRACE, "Enter\n"); 4395 brcmf_dbg(TRACE, "Enter\n");
3913 4396
3914 brcmf_get_assoc_ies(cfg); 4397 brcmf_get_assoc_ies(cfg, ifp);
3915 memcpy(profile->bssid, e->addr, ETH_ALEN); 4398 memcpy(profile->bssid, e->addr, ETH_ALEN);
3916 brcmf_update_bss_info(cfg); 4399 brcmf_update_bss_info(cfg, ifp);
3917 4400
3918 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); 4401 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3919 if (buf == NULL) { 4402 if (buf == NULL) {
@@ -3968,9 +4451,11 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3968 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING, 4451 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
3969 &ifp->vif->sme_state)) { 4452 &ifp->vif->sme_state)) {
3970 if (completed) { 4453 if (completed) {
3971 brcmf_get_assoc_ies(cfg); 4454 brcmf_get_assoc_ies(cfg, ifp);
3972 memcpy(profile->bssid, e->addr, ETH_ALEN); 4455 memcpy(profile->bssid, e->addr, ETH_ALEN);
3973 brcmf_update_bss_info(cfg); 4456 brcmf_update_bss_info(cfg, ifp);
4457 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4458 &ifp->vif->sme_state);
3974 } 4459 }
3975 cfg80211_connect_result(ndev, 4460 cfg80211_connect_result(ndev,
3976 (u8 *)profile->bssid, 4461 (u8 *)profile->bssid,
@@ -3981,9 +4466,6 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3981 completed ? WLAN_STATUS_SUCCESS : 4466 completed ? WLAN_STATUS_SUCCESS :
3982 WLAN_STATUS_AUTH_TIMEOUT, 4467 WLAN_STATUS_AUTH_TIMEOUT,
3983 GFP_KERNEL); 4468 GFP_KERNEL);
3984 if (completed)
3985 set_bit(BRCMF_VIF_STATUS_CONNECTED,
3986 &ifp->vif->sme_state);
3987 brcmf_dbg(CONN, "Report connect result - connection %s\n", 4469 brcmf_dbg(CONN, "Report connect result - connection %s\n",
3988 completed ? "succeeded" : "failed"); 4470 completed ? "succeeded" : "failed");
3989 } 4471 }
@@ -3996,38 +4478,38 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
3996 struct net_device *ndev, 4478 struct net_device *ndev,
3997 const struct brcmf_event_msg *e, void *data) 4479 const struct brcmf_event_msg *e, void *data)
3998{ 4480{
3999 s32 err = 0; 4481 static int generation;
4000 u32 event = e->event_code; 4482 u32 event = e->event_code;
4001 u32 reason = e->reason; 4483 u32 reason = e->reason;
4002 u32 len = e->datalen;
4003 static int generation;
4004
4005 struct station_info sinfo; 4484 struct station_info sinfo;
4006 4485
4007 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason); 4486 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4008 memset(&sinfo, 0, sizeof(sinfo)); 4487 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4488 ndev != cfg_to_ndev(cfg)) {
4489 brcmf_dbg(CONN, "AP mode link down\n");
4490 complete(&cfg->vif_disabled);
4491 return 0;
4492 }
4009 4493
4010 sinfo.filled = 0;
4011 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && 4494 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4012 reason == BRCMF_E_STATUS_SUCCESS) { 4495 (reason == BRCMF_E_STATUS_SUCCESS)) {
4496 memset(&sinfo, 0, sizeof(sinfo));
4013 sinfo.filled = STATION_INFO_ASSOC_REQ_IES; 4497 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4014 if (!data) { 4498 if (!data) {
4015 brcmf_err("No IEs present in ASSOC/REASSOC_IND"); 4499 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4016 return -EINVAL; 4500 return -EINVAL;
4017 } 4501 }
4018 sinfo.assoc_req_ies = data; 4502 sinfo.assoc_req_ies = data;
4019 sinfo.assoc_req_ies_len = len; 4503 sinfo.assoc_req_ies_len = e->datalen;
4020 generation++; 4504 generation++;
4021 sinfo.generation = generation; 4505 sinfo.generation = generation;
4022 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC); 4506 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4023 } else if ((event == BRCMF_E_DISASSOC_IND) || 4507 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4024 (event == BRCMF_E_DEAUTH_IND) || 4508 (event == BRCMF_E_DEAUTH_IND) ||
4025 (event == BRCMF_E_DEAUTH)) { 4509 (event == BRCMF_E_DEAUTH)) {
4026 generation++; 4510 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4027 sinfo.generation = generation;
4028 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4029 } 4511 }
4030 return err; 4512 return 0;
4031} 4513}
4032 4514
4033static s32 4515static s32
@@ -4064,6 +4546,8 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4064 } 4546 }
4065 brcmf_link_down(ifp->vif); 4547 brcmf_link_down(ifp->vif);
4066 brcmf_init_prof(ndev_to_prof(ndev)); 4548 brcmf_init_prof(ndev_to_prof(ndev));
4549 if (ndev != cfg_to_ndev(cfg))
4550 complete(&cfg->vif_disabled);
4067 } else if (brcmf_is_nonetwork(cfg, e)) { 4551 } else if (brcmf_is_nonetwork(cfg, e)) {
4068 if (brcmf_is_ibssmode(ifp->vif)) 4552 if (brcmf_is_ibssmode(ifp->vif))
4069 clear_bit(BRCMF_VIF_STATUS_CONNECTING, 4553 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
@@ -4112,6 +4596,57 @@ brcmf_notify_mic_status(struct brcmf_if *ifp,
4112 return 0; 4596 return 0;
4113} 4597}
4114 4598
4599static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4600 const struct brcmf_event_msg *e, void *data)
4601{
4602 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4603 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4604 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4605 struct brcmf_cfg80211_vif *vif;
4606
4607 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4608 ifevent->action, ifevent->flags, ifevent->ifidx,
4609 ifevent->bssidx);
4610
4611 mutex_lock(&event->vif_event_lock);
4612 event->action = ifevent->action;
4613 vif = event->vif;
4614
4615 switch (ifevent->action) {
4616 case BRCMF_E_IF_ADD:
4617 /* waiting process may have timed out */
4618 if (!cfg->vif_event.vif)
4619 return -EBADF;
4620
4621 ifp->vif = vif;
4622 vif->ifp = ifp;
4623 vif->wdev.netdev = ifp->ndev;
4624 ifp->ndev->ieee80211_ptr = &vif->wdev;
4625 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4626 mutex_unlock(&event->vif_event_lock);
4627 wake_up(&event->vif_wq);
4628 return 0;
4629
4630 case BRCMF_E_IF_DEL:
4631 ifp->vif = NULL;
4632 mutex_unlock(&event->vif_event_lock);
4633 /* event may not be upon user request */
4634 if (brcmf_cfg80211_vif_event_armed(cfg))
4635 wake_up(&event->vif_wq);
4636 return 0;
4637
4638 case BRCMF_E_IF_CHANGE:
4639 mutex_unlock(&event->vif_event_lock);
4640 wake_up(&event->vif_wq);
4641 return 0;
4642
4643 default:
4644 mutex_unlock(&event->vif_event_lock);
4645 break;
4646 }
4647 return -EINVAL;
4648}
4649
4115static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) 4650static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4116{ 4651{
4117 conf->frag_threshold = (u32)-1; 4652 conf->frag_threshold = (u32)-1;
@@ -4143,6 +4678,18 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4143 brcmf_notify_connect_status); 4678 brcmf_notify_connect_status);
4144 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, 4679 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4145 brcmf_notify_sched_scan_results); 4680 brcmf_notify_sched_scan_results);
4681 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4682 brcmf_notify_vif_event);
4683 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4684 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4685 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4686 brcmf_p2p_notify_listen_complete);
4687 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4688 brcmf_p2p_notify_action_frame_rx);
4689 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4690 brcmf_p2p_notify_action_tx_complete);
4691 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4692 brcmf_p2p_notify_action_tx_complete);
4146} 4693}
4147 4694
4148static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) 4695static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
@@ -4198,7 +4745,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4198 mutex_init(&cfg->usr_sync); 4745 mutex_init(&cfg->usr_sync);
4199 brcmf_init_escan(cfg); 4746 brcmf_init_escan(cfg);
4200 brcmf_init_conf(cfg->conf); 4747 brcmf_init_conf(cfg->conf);
4201 4748 init_completion(&cfg->vif_disabled);
4202 return err; 4749 return err;
4203} 4750}
4204 4751
@@ -4209,6 +4756,12 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4209 brcmf_deinit_priv_mem(cfg); 4756 brcmf_deinit_priv_mem(cfg);
4210} 4757}
4211 4758
4759static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4760{
4761 init_waitqueue_head(&event->vif_wq);
4762 mutex_init(&event->vif_event_lock);
4763}
4764
4212struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, 4765struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4213 struct device *busdev) 4766 struct device *busdev)
4214{ 4767{
@@ -4232,25 +4785,41 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4232 cfg = wiphy_priv(wiphy); 4785 cfg = wiphy_priv(wiphy);
4233 cfg->wiphy = wiphy; 4786 cfg->wiphy = wiphy;
4234 cfg->pub = drvr; 4787 cfg->pub = drvr;
4788 init_vif_event(&cfg->vif_event);
4235 INIT_LIST_HEAD(&cfg->vif_list); 4789 INIT_LIST_HEAD(&cfg->vif_list);
4236 4790
4237 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false); 4791 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4238 if (IS_ERR(vif)) { 4792 if (IS_ERR(vif)) {
4239 wiphy_free(wiphy); 4793 wiphy_free(wiphy);
4240 return NULL; 4794 return NULL;
4241 } 4795 }
4242 4796
4797 vif->ifp = ifp;
4798 vif->wdev.netdev = ndev;
4799 ndev->ieee80211_ptr = &vif->wdev;
4800 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4801
4243 err = wl_init_priv(cfg); 4802 err = wl_init_priv(cfg);
4244 if (err) { 4803 if (err) {
4245 brcmf_err("Failed to init iwm_priv (%d)\n", err); 4804 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4246 goto cfg80211_attach_out; 4805 goto cfg80211_attach_out;
4247 } 4806 }
4248
4249 ifp->vif = vif; 4807 ifp->vif = vif;
4808
4809 err = brcmf_p2p_attach(cfg);
4810 if (err) {
4811 brcmf_err("P2P initilisation failed (%d)\n", err);
4812 goto cfg80211_p2p_attach_out;
4813 }
4814
4250 return cfg; 4815 return cfg;
4251 4816
4817cfg80211_p2p_attach_out:
4818 wl_deinit_priv(cfg);
4819
4252cfg80211_attach_out: 4820cfg80211_attach_out:
4253 brcmf_free_vif(vif); 4821 brcmf_free_vif(vif);
4822 wiphy_free(wiphy);
4254 return NULL; 4823 return NULL;
4255} 4824}
4256 4825
@@ -4489,3 +5058,57 @@ s32 brcmf_cfg80211_down(struct net_device *ndev)
4489 return err; 5058 return err;
4490} 5059}
4491 5060
5061u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5062{
5063 struct brcmf_cfg80211_vif *vif;
5064 bool result = 0;
5065
5066 list_for_each_entry(vif, &cfg->vif_list, list) {
5067 if (test_bit(state, &vif->sme_state))
5068 result++;
5069 }
5070 return result;
5071}
5072
5073static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5074 u8 action)
5075{
5076 u8 evt_action;
5077
5078 mutex_lock(&event->vif_event_lock);
5079 evt_action = event->action;
5080 mutex_unlock(&event->vif_event_lock);
5081 return evt_action == action;
5082}
5083
5084void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5085 struct brcmf_cfg80211_vif *vif)
5086{
5087 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5088
5089 mutex_lock(&event->vif_event_lock);
5090 event->vif = vif;
5091 event->action = 0;
5092 mutex_unlock(&event->vif_event_lock);
5093}
5094
5095bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5096{
5097 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5098 bool armed;
5099
5100 mutex_lock(&event->vif_event_lock);
5101 armed = event->vif != NULL;
5102 mutex_unlock(&event->vif_event_lock);
5103
5104 return armed;
5105}
5106int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5107 u8 action, ulong timeout)
5108{
5109 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5110
5111 return wait_event_timeout(event->vif_wq,
5112 vif_event_equals(event, action), timeout);
5113}
5114
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index e4d9cc7a8e63..8b5d4989906c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -41,6 +41,38 @@
41#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ 41#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
42#define IE_MAX_LEN 512 42#define IE_MAX_LEN 512
43 43
44/* IE TLV processing */
45#define TLV_LEN_OFF 1 /* length offset */
46#define TLV_HDR_LEN 2 /* header length */
47#define TLV_BODY_OFF 2 /* body offset */
48#define TLV_OUI_LEN 3 /* oui id length */
49
50/* 802.11 Mgmt Packet flags */
51#define BRCMF_VNDR_IE_BEACON_FLAG 0x1
52#define BRCMF_VNDR_IE_PRBRSP_FLAG 0x2
53#define BRCMF_VNDR_IE_ASSOCRSP_FLAG 0x4
54#define BRCMF_VNDR_IE_AUTHRSP_FLAG 0x8
55#define BRCMF_VNDR_IE_PRBREQ_FLAG 0x10
56#define BRCMF_VNDR_IE_ASSOCREQ_FLAG 0x20
57/* vendor IE in IW advertisement protocol ID field */
58#define BRCMF_VNDR_IE_IWAPID_FLAG 0x40
59/* allow custom IE id */
60#define BRCMF_VNDR_IE_CUSTOM_FLAG 0x100
61
62/* P2P Action Frames flags (spec ordered) */
63#define BRCMF_VNDR_IE_GONREQ_FLAG 0x001000
64#define BRCMF_VNDR_IE_GONRSP_FLAG 0x002000
65#define BRCMF_VNDR_IE_GONCFM_FLAG 0x004000
66#define BRCMF_VNDR_IE_INVREQ_FLAG 0x008000
67#define BRCMF_VNDR_IE_INVRSP_FLAG 0x010000
68#define BRCMF_VNDR_IE_DISREQ_FLAG 0x020000
69#define BRCMF_VNDR_IE_DISRSP_FLAG 0x040000
70#define BRCMF_VNDR_IE_PRDREQ_FLAG 0x080000
71#define BRCMF_VNDR_IE_PRDRSP_FLAG 0x100000
72
73#define BRCMF_VNDR_IE_P2PAF_SHIFT 12
74
75
44/** 76/**
45 * enum brcmf_scan_status - dongle scan status 77 * enum brcmf_scan_status - dongle scan status
46 * 78 *
@@ -52,11 +84,19 @@ enum brcmf_scan_status {
52 BRCMF_SCAN_STATUS_ABORT, 84 BRCMF_SCAN_STATUS_ABORT,
53}; 85};
54 86
55/* wi-fi mode */ 87/**
88 * enum wl_mode - driver mode of virtual interface.
89 *
90 * @WL_MODE_BSS: connects to BSS.
91 * @WL_MODE_IBSS: operate as ad-hoc.
92 * @WL_MODE_AP: operate as access-point.
93 * @WL_MODE_P2P: provide P2P discovery.
94 */
56enum wl_mode { 95enum wl_mode {
57 WL_MODE_BSS, 96 WL_MODE_BSS,
58 WL_MODE_IBSS, 97 WL_MODE_IBSS,
59 WL_MODE_AP 98 WL_MODE_AP,
99 WL_MODE_P2P
60}; 100};
61 101
62/* dongle configuration */ 102/* dongle configuration */
@@ -108,6 +148,7 @@ struct brcmf_cfg80211_profile {
108 * @BRCMF_VIF_STATUS_READY: ready for operation. 148 * @BRCMF_VIF_STATUS_READY: ready for operation.
109 * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress. 149 * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress.
110 * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully. 150 * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully.
151 * @BRCMF_VIF_STATUS_DISCONNECTING: disconnect/disable in progress.
111 * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation. 152 * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation.
112 * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started. 153 * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started.
113 */ 154 */
@@ -115,6 +156,7 @@ enum brcmf_vif_status {
115 BRCMF_VIF_STATUS_READY, 156 BRCMF_VIF_STATUS_READY,
116 BRCMF_VIF_STATUS_CONNECTING, 157 BRCMF_VIF_STATUS_CONNECTING,
117 BRCMF_VIF_STATUS_CONNECTED, 158 BRCMF_VIF_STATUS_CONNECTED,
159 BRCMF_VIF_STATUS_DISCONNECTING,
118 BRCMF_VIF_STATUS_AP_CREATING, 160 BRCMF_VIF_STATUS_AP_CREATING,
119 BRCMF_VIF_STATUS_AP_CREATED 161 BRCMF_VIF_STATUS_AP_CREATED
120}; 162};
@@ -122,16 +164,22 @@ enum brcmf_vif_status {
122/** 164/**
123 * struct vif_saved_ie - holds saved IEs for a virtual interface. 165 * struct vif_saved_ie - holds saved IEs for a virtual interface.
124 * 166 *
167 * @probe_req_ie: IE info for probe request.
125 * @probe_res_ie: IE info for probe response. 168 * @probe_res_ie: IE info for probe response.
126 * @beacon_ie: IE info for beacon frame. 169 * @beacon_ie: IE info for beacon frame.
170 * @probe_req_ie_len: IE info length for probe request.
127 * @probe_res_ie_len: IE info length for probe response. 171 * @probe_res_ie_len: IE info length for probe response.
128 * @beacon_ie_len: IE info length for beacon frame. 172 * @beacon_ie_len: IE info length for beacon frame.
129 */ 173 */
130struct vif_saved_ie { 174struct vif_saved_ie {
175 u8 probe_req_ie[IE_MAX_LEN];
131 u8 probe_res_ie[IE_MAX_LEN]; 176 u8 probe_res_ie[IE_MAX_LEN];
132 u8 beacon_ie[IE_MAX_LEN]; 177 u8 beacon_ie[IE_MAX_LEN];
178 u8 assoc_req_ie[IE_MAX_LEN];
179 u32 probe_req_ie_len;
133 u32 probe_res_ie_len; 180 u32 probe_res_ie_len;
134 u32 beacon_ie_len; 181 u32 beacon_ie_len;
182 u32 assoc_req_ie_len;
135}; 183};
136 184
137/** 185/**
@@ -145,6 +193,7 @@ struct vif_saved_ie {
145 * @sme_state: SME state using enum brcmf_vif_status bits. 193 * @sme_state: SME state using enum brcmf_vif_status bits.
146 * @pm_block: power-management blocked. 194 * @pm_block: power-management blocked.
147 * @list: linked list. 195 * @list: linked list.
196 * @mgmt_rx_reg: registered rx mgmt frame types.
148 */ 197 */
149struct brcmf_cfg80211_vif { 198struct brcmf_cfg80211_vif {
150 struct brcmf_if *ifp; 199 struct brcmf_if *ifp;
@@ -156,6 +205,7 @@ struct brcmf_cfg80211_vif {
156 bool pm_block; 205 bool pm_block;
157 struct vif_saved_ie saved_ie; 206 struct vif_saved_ie saved_ie;
158 struct list_head list; 207 struct list_head list;
208 u16 mgmt_rx_reg;
159}; 209};
160 210
161/* association inform */ 211/* association inform */
@@ -189,6 +239,9 @@ struct escan_info {
189 u8 escan_buf[WL_ESCAN_BUF_SIZE]; 239 u8 escan_buf[WL_ESCAN_BUF_SIZE];
190 struct wiphy *wiphy; 240 struct wiphy *wiphy;
191 struct net_device *ndev; 241 struct net_device *ndev;
242 s32 (*run)(struct brcmf_cfg80211_info *cfg,
243 struct net_device *ndev,
244 struct cfg80211_scan_request *request, u16 action);
192}; 245};
193 246
194/** 247/**
@@ -273,10 +326,27 @@ struct brcmf_pno_scanresults_le {
273}; 326};
274 327
275/** 328/**
329 * struct brcmf_cfg80211_vif_event - virtual interface event information.
330 *
331 * @vif_wq: waitqueue awaiting interface event from firmware.
332 * @vif_event_lock: protects other members in this structure.
333 * @vif_complete: completion for net attach.
334 * @action: either add, change, or delete.
335 * @vif: virtual interface object related to the event.
336 */
337struct brcmf_cfg80211_vif_event {
338 wait_queue_head_t vif_wq;
339 struct mutex vif_event_lock;
340 u8 action;
341 struct brcmf_cfg80211_vif *vif;
342};
343
344/**
276 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface 345 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
277 * 346 *
278 * @wiphy: wiphy object for cfg80211 interface. 347 * @wiphy: wiphy object for cfg80211 interface.
279 * @conf: dongle configuration. 348 * @conf: dongle configuration.
349 * @p2p: peer-to-peer specific information.
280 * @scan_request: cfg80211 scan request object. 350 * @scan_request: cfg80211 scan request object.
281 * @usr_sync: mainly for dongle up/down synchronization. 351 * @usr_sync: mainly for dongle up/down synchronization.
282 * @bss_list: bss_list holding scanned ap information. 352 * @bss_list: bss_list holding scanned ap information.
@@ -304,10 +374,12 @@ struct brcmf_pno_scanresults_le {
304 * @escan_ioctl_buf: dongle command buffer for escan commands. 374 * @escan_ioctl_buf: dongle command buffer for escan commands.
305 * @vif_list: linked list of vif instances. 375 * @vif_list: linked list of vif instances.
306 * @vif_cnt: number of vif instances. 376 * @vif_cnt: number of vif instances.
377 * @vif_event: vif event signalling.
307 */ 378 */
308struct brcmf_cfg80211_info { 379struct brcmf_cfg80211_info {
309 struct wiphy *wiphy; 380 struct wiphy *wiphy;
310 struct brcmf_cfg80211_conf *conf; 381 struct brcmf_cfg80211_conf *conf;
382 struct brcmf_p2p_info p2p;
311 struct cfg80211_scan_request *scan_request; 383 struct cfg80211_scan_request *scan_request;
312 struct mutex usr_sync; 384 struct mutex usr_sync;
313 struct brcmf_scan_results *bss_list; 385 struct brcmf_scan_results *bss_list;
@@ -335,6 +407,21 @@ struct brcmf_cfg80211_info {
335 u8 *escan_ioctl_buf; 407 u8 *escan_ioctl_buf;
336 struct list_head vif_list; 408 struct list_head vif_list;
337 u8 vif_cnt; 409 u8 vif_cnt;
410 struct brcmf_cfg80211_vif_event vif_event;
411 struct completion vif_disabled;
412};
413
414/**
415 * struct brcmf_tlv - tag_ID/length/value_buffer tuple.
416 *
417 * @id: tag identifier.
418 * @len: number of bytes in value buffer.
419 * @data: value buffer.
420 */
421struct brcmf_tlv {
422 u8 id;
423 u8 len;
424 u8 data[1];
338}; 425};
339 426
340static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg) 427static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg)
@@ -389,4 +476,26 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
389s32 brcmf_cfg80211_up(struct net_device *ndev); 476s32 brcmf_cfg80211_up(struct net_device *ndev);
390s32 brcmf_cfg80211_down(struct net_device *ndev); 477s32 brcmf_cfg80211_down(struct net_device *ndev);
391 478
479struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
480 enum nl80211_iftype type,
481 bool pm_block);
482void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
483
484s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
485 const u8 *vndr_ie_buf, u32 vndr_ie_len);
486s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
487struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key);
488u16 channel_to_chanspec(struct ieee80211_channel *ch);
489u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
490void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
491 struct brcmf_cfg80211_vif *vif);
492bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
493int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
494 u8 action, ulong timeout);
495s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
496 struct net_device *ndev,
497 bool aborted, bool fw_abort);
498void brcmf_set_mpc(struct net_device *ndev, int mpc);
499void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
500
392#endif /* _wl_cfg80211_h_ */ 501#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index cdb62b8ccc79..10ee314c4229 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -183,8 +183,7 @@ static bool brcms_c_country_valid(const char *ccode)
183 * chars. 183 * chars.
184 */ 184 */
185 if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A && 185 if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
186 (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A && 186 (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A))
187 ccode[2] == '\0'))
188 return false; 187 return false;
189 188
190 /* 189 /*
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 62be5502b95d..8ef02dca8f8c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -101,8 +101,6 @@
101#define DOT11_RTS_LEN 16 101#define DOT11_RTS_LEN 16
102#define DOT11_CTS_LEN 10 102#define DOT11_CTS_LEN 10
103#define DOT11_BA_BITMAP_LEN 128 103#define DOT11_BA_BITMAP_LEN 128
104#define DOT11_MIN_BEACON_PERIOD 1
105#define DOT11_MAX_BEACON_PERIOD 0xFFFF
106#define DOT11_MAXNUMFRAGS 16 104#define DOT11_MAXNUMFRAGS 16
107#define DOT11_MAX_FRAG_LEN 2346 105#define DOT11_MAX_FRAG_LEN 2346
108 106
@@ -3140,8 +3138,7 @@ void brcms_c_reset(struct brcms_c_info *wlc)
3140 brcms_c_statsupd(wlc); 3138 brcms_c_statsupd(wlc);
3141 3139
3142 /* reset our snapshot of macstat counters */ 3140 /* reset our snapshot of macstat counters */
3143 memset((char *)wlc->core->macstat_snapshot, 0, 3141 memset(wlc->core->macstat_snapshot, 0, sizeof(struct macstat));
3144 sizeof(struct macstat));
3145 3142
3146 brcms_b_reset(wlc->hw); 3143 brcms_b_reset(wlc->hw);
3147} 3144}
@@ -4054,7 +4051,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4054 return; 4051 return;
4055 } 4052 }
4056 4053
4057 memset((char *)&acp_shm, 0, sizeof(struct shm_acparams)); 4054 memset(&acp_shm, 0, sizeof(struct shm_acparams));
4058 /* fill in shm ac params struct */ 4055 /* fill in shm ac params struct */
4059 acp_shm.txop = params->txop; 4056 acp_shm.txop = params->txop;
4060 /* convert from units of 32us to us for ucode */ 4057 /* convert from units of 32us to us for ucode */
@@ -4770,7 +4767,7 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
4770 struct brcms_bss_info *bi = wlc->default_bss; 4767 struct brcms_bss_info *bi = wlc->default_bss;
4771 4768
4772 /* init default and target BSS with some sane initial values */ 4769 /* init default and target BSS with some sane initial values */
4773 memset((char *)(bi), 0, sizeof(struct brcms_bss_info)); 4770 memset(bi, 0, sizeof(*bi));
4774 bi->beacon_period = BEACON_INTERVAL_DEFAULT; 4771 bi->beacon_period = BEACON_INTERVAL_DEFAULT;
4775 4772
4776 /* fill the default channel as the first valid channel 4773 /* fill the default channel as the first valid channel
@@ -5299,7 +5296,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
5299 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); 5296 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
5300 5297
5301 /* Clear rateset override */ 5298 /* Clear rateset override */
5302 memset(&rs, 0, sizeof(struct brcms_c_rateset)); 5299 memset(&rs, 0, sizeof(rs));
5303 5300
5304 switch (gmode) { 5301 switch (gmode) {
5305 case GMODE_LEGACY_B: 5302 case GMODE_LEGACY_B:
@@ -5522,7 +5519,7 @@ int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5522 if (rs->count > BRCMS_NUMRATES) 5519 if (rs->count > BRCMS_NUMRATES)
5523 return -ENOBUFS; 5520 return -ENOBUFS;
5524 5521
5525 memset(&internal_rs, 0, sizeof(struct brcms_c_rateset)); 5522 memset(&internal_rs, 0, sizeof(internal_rs));
5526 5523
5527 /* Copy only legacy rateset section */ 5524 /* Copy only legacy rateset section */
5528 internal_rs.count = rs->count; 5525 internal_rs.count = rs->count;
@@ -5548,8 +5545,7 @@ int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5548 5545
5549int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) 5546int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
5550{ 5547{
5551 if (period < DOT11_MIN_BEACON_PERIOD || 5548 if (period == 0)
5552 period > DOT11_MAX_BEACON_PERIOD)
5553 return -EINVAL; 5549 return -EINVAL;
5554 5550
5555 wlc->default_bss->beacon_period = period; 5551 wlc->default_bss->beacon_period = period;
@@ -5626,7 +5622,7 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
5626 for (i = 0; i < BRCMS_MAXMODULES; i++) { 5622 for (i = 0; i < BRCMS_MAXMODULES; i++) {
5627 if (!strcmp(wlc->modulecb[i].name, name) && 5623 if (!strcmp(wlc->modulecb[i].name, name) &&
5628 (wlc->modulecb[i].hdl == hdl)) { 5624 (wlc->modulecb[i].hdl == hdl)) {
5629 memset(&wlc->modulecb[i], 0, sizeof(struct modulecb)); 5625 memset(&wlc->modulecb[i], 0, sizeof(wlc->modulecb[i]));
5630 return 0; 5626 return 0;
5631 } 5627 }
5632 } 5628 }
@@ -6446,10 +6442,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6446 6442
6447 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) 6443 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
6448 && (!is_mcs_rate(rspec[k]))) { 6444 && (!is_mcs_rate(rspec[k]))) {
6449 brcms_err(wlc->hw->d11core, 6445 brcms_warn(wlc->hw->d11core,
6450 "wl%d: %s: IEEE80211_TX_" 6446 "wl%d: %s: IEEE80211_TX_RC_MCS != is_mcs_rate(rspec)\n",
6451 "RC_MCS != is_mcs_rate(rspec)\n", 6447 wlc->pub->unit, __func__);
6452 wlc->pub->unit, __func__);
6453 } 6448 }
6454 6449
6455 if (is_mcs_rate(rspec[k])) { 6450 if (is_mcs_rate(rspec[k])) {
@@ -6682,11 +6677,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6682 (struct ofdm_phy_hdr *) rts_plcp) : 6677 (struct ofdm_phy_hdr *) rts_plcp) :
6683 rts_plcp[0]) << 8; 6678 rts_plcp[0]) << 8;
6684 } else { 6679 } else {
6685 memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); 6680 memset(txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
6686 memset((char *)&txh->rts_frame, 0, 6681 memset(&txh->rts_frame, 0, sizeof(struct ieee80211_rts));
6687 sizeof(struct ieee80211_rts)); 6682 memset(txh->RTSPLCPFallback, 0, sizeof(txh->RTSPLCPFallback));
6688 memset((char *)txh->RTSPLCPFallback, 0,
6689 sizeof(txh->RTSPLCPFallback));
6690 txh->RTSDurFallback = 0; 6683 txh->RTSDurFallback = 0;
6691 } 6684 }
6692 6685
@@ -6841,21 +6834,19 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6841 wlc->fragthresh[queue] = 6834 wlc->fragthresh[queue] =
6842 (u16) newfragthresh; 6835 (u16) newfragthresh;
6843 } else { 6836 } else {
6844 brcms_err(wlc->hw->d11core, 6837 brcms_warn(wlc->hw->d11core,
6845 "wl%d: %s txop invalid " 6838 "wl%d: %s txop invalid for rate %d\n",
6846 "for rate %d\n", 6839 wlc->pub->unit, fifo_names[queue],
6847 wlc->pub->unit, fifo_names[queue], 6840 rspec2rate(rspec[0]));
6848 rspec2rate(rspec[0]));
6849 } 6841 }
6850 6842
6851 if (dur > wlc->edcf_txop[ac]) 6843 if (dur > wlc->edcf_txop[ac])
6852 brcms_err(wlc->hw->d11core, 6844 brcms_warn(wlc->hw->d11core,
6853 "wl%d: %s: %s txop " 6845 "wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n",
6854 "exceeded phylen %d/%d dur %d/%d\n", 6846 wlc->pub->unit, __func__,
6855 wlc->pub->unit, __func__, 6847 fifo_names[queue],
6856 fifo_names[queue], 6848 phylen, wlc->fragthresh[queue],
6857 phylen, wlc->fragthresh[queue], 6849 dur, wlc->edcf_txop[ac]);
6858 dur, wlc->edcf_txop[ac]);
6859 } 6850 }
6860 } 6851 }
6861 6852
@@ -7330,7 +7321,7 @@ brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
7330 *len = hdr_len + body_len; 7321 *len = hdr_len + body_len;
7331 7322
7332 /* format PHY and MAC headers */ 7323 /* format PHY and MAC headers */
7333 memset((char *)buf, 0, hdr_len); 7324 memset(buf, 0, hdr_len);
7334 7325
7335 plcp = (struct cck_phy_hdr *) buf; 7326 plcp = (struct cck_phy_hdr *) buf;
7336 7327
@@ -7401,9 +7392,13 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7401 struct brcms_bss_cfg *cfg, 7392 struct brcms_bss_cfg *cfg,
7402 bool suspend) 7393 bool suspend)
7403{ 7394{
7404 u16 prb_resp[BCN_TMPL_LEN / 2]; 7395 u16 *prb_resp;
7405 int len = BCN_TMPL_LEN; 7396 int len = BCN_TMPL_LEN;
7406 7397
7398 prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
7399 if (!prb_resp)
7400 return;
7401
7407 /* 7402 /*
7408 * write the probe response to hardware, or save in 7403 * write the probe response to hardware, or save in
7409 * the config structure 7404 * the config structure
@@ -7437,6 +7432,8 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
7437 7432
7438 if (suspend) 7433 if (suspend)
7439 brcms_c_enable_mac(wlc); 7434 brcms_c_enable_mac(wlc);
7435
7436 kfree(prb_resp);
7440} 7437}
7441 7438
7442void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) 7439void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)