aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2014-07-30 07:20:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-31 13:45:29 -0400
commit70b7d94bcc1266fb91686bcd539ef81dff40eb3a (patch)
treebaabcc025bfa4210560caaf2b28d7beb52402cc6
parent17ca5c718414d605f0060336e071fb77359be790 (diff)
brcmfmac: Add TDLS support to msgbuf.
TDLS connections require dedicated flowrings. This patches adds TDLS event handling and flowring creation/deletion based on these events. Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.c94
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.h9
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.h7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c24
9 files changed, 158 insertions, 6 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
index 10b48c2c4b36..a159ff3427de 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -349,6 +349,12 @@ brcmf_proto_bcdc_delete_peer(struct brcmf_pub *drvr, int ifidx,
349{ 349{
350} 350}
351 351
352static void
353brcmf_proto_bcdc_add_tdls_peer(struct brcmf_pub *drvr, int ifidx,
354 u8 peer[ETH_ALEN])
355{
356}
357
352int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) 358int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
353{ 359{
354 struct brcmf_bcdc *bcdc; 360 struct brcmf_bcdc *bcdc;
@@ -369,6 +375,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
369 drvr->proto->txdata = brcmf_proto_bcdc_txdata; 375 drvr->proto->txdata = brcmf_proto_bcdc_txdata;
370 drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode; 376 drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode;
371 drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer; 377 drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
378 drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
372 drvr->proto->pd = bcdc; 379 drvr->proto->pd = bcdc;
373 380
374 drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; 381 drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
index 07009046fda5..a1016b811284 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
@@ -49,6 +49,23 @@ static const u8 brcmf_flowring_prio2fifo[] = {
49}; 49};
50 50
51 51
52static bool
53brcmf_flowring_is_tdls_mac(struct brcmf_flowring *flow, u8 mac[ETH_ALEN])
54{
55 struct brcmf_flowring_tdls_entry *search;
56
57 search = flow->tdls_entry;
58
59 while (search) {
60 if (memcmp(search->mac, mac, ETH_ALEN) == 0)
61 return true;
62 search = search->next;
63 }
64
65 return false;
66}
67
68
52u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN], 69u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
53 u8 prio, u8 ifidx) 70 u8 prio, u8 ifidx)
54{ 71{
@@ -67,6 +84,10 @@ u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
67 mac = (u8 *)ALLFFMAC; 84 mac = (u8 *)ALLFFMAC;
68 fifo = 0; 85 fifo = 0;
69 } 86 }
87 if ((sta) && (flow->tdls_active) &&
88 (brcmf_flowring_is_tdls_mac(flow, da))) {
89 sta = false;
90 }
70 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) : 91 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) :
71 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx); 92 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx);
72 found = false; 93 found = false;
@@ -106,15 +127,17 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
106 mac = (u8 *)ALLFFMAC; 127 mac = (u8 *)ALLFFMAC;
107 fifo = 0; 128 fifo = 0;
108 } 129 }
130 if ((sta) && (flow->tdls_active) &&
131 (brcmf_flowring_is_tdls_mac(flow, da))) {
132 sta = false;
133 }
109 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) : 134 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) :
110 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx); 135 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx);
111 found = false; 136 found = false;
112 hash = flow->hash; 137 hash = flow->hash;
113 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { 138 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
114 if (((sta) && 139 if ((hash[hash_idx].ifidx == BRCMF_FLOWRING_INVALID_IFIDX) &&
115 (hash[hash_idx].ifidx == BRCMF_FLOWRING_INVALID_IFIDX)) || 140 (memcmp(hash[hash_idx].mac, ALLZEROMAC, ETH_ALEN) == 0)) {
116 ((!sta) &&
117 (memcmp(hash[hash_idx].mac, ALLZEROMAC, ETH_ALEN) == 0))) {
118 found = true; 141 found = true;
119 break; 142 break;
120 } 143 }
@@ -356,12 +379,21 @@ void brcmf_flowring_detach(struct brcmf_flowring *flow)
356{ 379{
357 struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); 380 struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
358 struct brcmf_pub *drvr = bus_if->drvr; 381 struct brcmf_pub *drvr = bus_if->drvr;
382 struct brcmf_flowring_tdls_entry *search;
383 struct brcmf_flowring_tdls_entry *remove;
359 u8 flowid; 384 u8 flowid;
360 385
361 for (flowid = 0; flowid < flow->nrofrings; flowid++) { 386 for (flowid = 0; flowid < flow->nrofrings; flowid++) {
362 if (flow->rings[flowid]) 387 if (flow->rings[flowid])
363 brcmf_msgbuf_delete_flowring(drvr, flowid); 388 brcmf_msgbuf_delete_flowring(drvr, flowid);
364 } 389 }
390
391 search = flow->tdls_entry;
392 while (search) {
393 remove = search;
394 search = search->next;
395 kfree(remove);
396 }
365 kfree(flow->rings); 397 kfree(flow->rings);
366 kfree(flow); 398 kfree(flow);
367} 399}
@@ -396,11 +428,25 @@ void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
396 struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); 428 struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
397 struct brcmf_pub *drvr = bus_if->drvr; 429 struct brcmf_pub *drvr = bus_if->drvr;
398 struct brcmf_flowring_hash *hash; 430 struct brcmf_flowring_hash *hash;
431 struct brcmf_flowring_tdls_entry *prev;
432 struct brcmf_flowring_tdls_entry *search;
399 u32 i; 433 u32 i;
400 u8 flowid; 434 u8 flowid;
401 bool sta; 435 bool sta;
402 436
403 sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT); 437 sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT);
438
439 search = flow->tdls_entry;
440 prev = NULL;
441 while (search) {
442 if (memcmp(search->mac, peer, ETH_ALEN) == 0) {
443 sta = false;
444 break;
445 }
446 prev = search;
447 search = search->next;
448 }
449
404 hash = flow->hash; 450 hash = flow->hash;
405 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { 451 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
406 if ((sta || (memcmp(hash[i].mac, peer, ETH_ALEN) == 0)) && 452 if ((sta || (memcmp(hash[i].mac, peer, ETH_ALEN) == 0)) &&
@@ -412,4 +458,44 @@ void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
412 } 458 }
413 } 459 }
414 } 460 }
461
462 if (search) {
463 if (prev)
464 prev->next = search->next;
465 else
466 flow->tdls_entry = search->next;
467 kfree(search);
468 if (flow->tdls_entry == NULL)
469 flow->tdls_active = false;
470 }
471}
472
473
474void brcmf_flowring_add_tdls_peer(struct brcmf_flowring *flow, int ifidx,
475 u8 peer[ETH_ALEN])
476{
477 struct brcmf_flowring_tdls_entry *tdls_entry;
478 struct brcmf_flowring_tdls_entry *search;
479
480 tdls_entry = kzalloc(sizeof(*tdls_entry), GFP_ATOMIC);
481 if (tdls_entry == NULL)
482 return;
483
484 memcpy(tdls_entry->mac, peer, ETH_ALEN);
485 tdls_entry->next = NULL;
486 if (flow->tdls_entry == NULL) {
487 flow->tdls_entry = tdls_entry;
488 } else {
489 search = flow->tdls_entry;
490 if (memcmp(search->mac, peer, ETH_ALEN) == 0)
491 return;
492 while (search->next) {
493 search = search->next;
494 if (memcmp(search->mac, peer, ETH_ALEN) == 0)
495 return;
496 }
497 search->next = tdls_entry;
498 }
499
500 flow->tdls_active = true;
415} 501}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.h b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
index cb9644ca6ece..a34cd394c616 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
@@ -40,6 +40,11 @@ struct brcmf_flowring_ring {
40 struct sk_buff_head skblist; 40 struct sk_buff_head skblist;
41}; 41};
42 42
43struct brcmf_flowring_tdls_entry {
44 u8 mac[ETH_ALEN];
45 struct brcmf_flowring_tdls_entry *next;
46};
47
43struct brcmf_flowring { 48struct brcmf_flowring {
44 struct device *dev; 49 struct device *dev;
45 struct brcmf_flowring_hash hash[BRCMF_FLOWRING_HASHSIZE]; 50 struct brcmf_flowring_hash hash[BRCMF_FLOWRING_HASHSIZE];
@@ -47,6 +52,8 @@ struct brcmf_flowring {
47 spinlock_t block_lock; 52 spinlock_t block_lock;
48 enum proto_addr_mode addr_mode[BRCMF_MAX_IFS]; 53 enum proto_addr_mode addr_mode[BRCMF_MAX_IFS];
49 u16 nrofrings; 54 u16 nrofrings;
55 bool tdls_active;
56 struct brcmf_flowring_tdls_entry *tdls_entry;
50}; 57};
51 58
52 59
@@ -70,6 +77,8 @@ void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,
70 enum proto_addr_mode addr_mode); 77 enum proto_addr_mode addr_mode);
71void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx, 78void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
72 u8 peer[ETH_ALEN]); 79 u8 peer[ETH_ALEN]);
80void brcmf_flowring_add_tdls_peer(struct brcmf_flowring *flow, int ifidx,
81 u8 peer[ETH_ALEN]);
73 82
74 83
75#endif /* BRCMFMAC_FLOWRING_H */ 84#endif /* BRCMFMAC_FLOWRING_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index fad77dd2a3a5..4f1daabc551b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -293,7 +293,11 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
293 goto event_free; 293 goto event_free;
294 } 294 }
295 295
296 ifp = drvr->iflist[emsg.bsscfgidx]; 296 if ((event->code == BRCMF_E_TDLS_PEER_EVENT) &&
297 (emsg.bsscfgidx == 1))
298 ifp = drvr->iflist[0];
299 else
300 ifp = drvr->iflist[emsg.bsscfgidx];
297 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, 301 err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg,
298 event->data); 302 event->data);
299 if (err) { 303 if (err) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 51b53a73d074..dd20b1862d44 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -102,6 +102,7 @@ struct brcmf_event;
102 BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ 102 BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
103 BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ 103 BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
104 BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ 104 BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
105 BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
105 BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ 106 BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
106 BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128) 107 BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128)
107 108
@@ -155,6 +156,10 @@ enum brcmf_fweh_event_code {
155#define BRCMF_E_REASON_TSPEC_REJECTED 7 156#define BRCMF_E_REASON_TSPEC_REJECTED 7
156#define BRCMF_E_REASON_BETTER_AP 8 157#define BRCMF_E_REASON_BETTER_AP 8
157 158
159#define BRCMF_E_REASON_TDLS_PEER_DISCOVERED 0
160#define BRCMF_E_REASON_TDLS_PEER_CONNECTED 1
161#define BRCMF_E_REASON_TDLS_PEER_DISCONNECTED 2
162
158/* action field values for brcmf_ifevent */ 163/* action field values for brcmf_ifevent */
159#define BRCMF_E_IF_ADD 1 164#define BRCMF_E_IF_ADD 1
160#define BRCMF_E_IF_DEL 2 165#define BRCMF_E_IF_DEL 2
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index c7a1c59ba6c3..535c7eb01b3a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -752,6 +752,15 @@ brcmf_msgbuf_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
752 752
753 753
754static void 754static void
755brcmf_msgbuf_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
756{
757 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
758
759 brcmf_flowring_add_tdls_peer(msgbuf->flow, ifidx, peer);
760}
761
762
763static void
755brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf) 764brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf)
756{ 765{
757 struct msgbuf_ioctl_resp_hdr *ioctl_resp; 766 struct msgbuf_ioctl_resp_hdr *ioctl_resp;
@@ -1298,6 +1307,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1298 drvr->proto->txdata = brcmf_msgbuf_txdata; 1307 drvr->proto->txdata = brcmf_msgbuf_txdata;
1299 drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode; 1308 drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode;
1300 drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; 1309 drvr->proto->delete_peer = brcmf_msgbuf_delete_peer;
1310 drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer;
1301 drvr->proto->pd = msgbuf; 1311 drvr->proto->pd = msgbuf;
1302 1312
1303 init_waitqueue_head(&msgbuf->ioctl_resp_wait); 1313 init_waitqueue_head(&msgbuf->ioctl_resp_wait);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
index 44b1cb466d4e..62b940723339 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
@@ -54,7 +54,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
54 if ((proto->txdata == NULL) || (proto->hdrpull == NULL) || 54 if ((proto->txdata == NULL) || (proto->hdrpull == NULL) ||
55 (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) || 55 (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) ||
56 (proto->configure_addr_mode == NULL) || 56 (proto->configure_addr_mode == NULL) ||
57 (proto->delete_peer == NULL)) { 57 (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL)) {
58 brcmf_err("Not all proto handlers have been installed\n"); 58 brcmf_err("Not all proto handlers have been installed\n");
59 goto fail; 59 goto fail;
60 } 60 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
index 55942e3561a3..971172ff686c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
@@ -36,6 +36,8 @@ struct brcmf_proto {
36 enum proto_addr_mode addr_mode); 36 enum proto_addr_mode addr_mode);
37 void (*delete_peer)(struct brcmf_pub *drvr, int ifidx, 37 void (*delete_peer)(struct brcmf_pub *drvr, int ifidx,
38 u8 peer[ETH_ALEN]); 38 u8 peer[ETH_ALEN]);
39 void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx,
40 u8 peer[ETH_ALEN]);
39 void *pd; 41 void *pd;
40}; 42};
41 43
@@ -74,6 +76,11 @@ brcmf_proto_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
74{ 76{
75 drvr->proto->delete_peer(drvr, ifidx, peer); 77 drvr->proto->delete_peer(drvr, ifidx, peer);
76} 78}
79static inline void
80brcmf_proto_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
81{
82 drvr->proto->add_tdls_peer(drvr, ifidx, peer);
83}
77 84
78 85
79#endif /* BRCMFMAC_PROTO_H */ 86#endif /* BRCMFMAC_PROTO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index a0e555a9f5f7..02fe706fc9ec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4155,6 +4155,27 @@ static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4155 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); 4155 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4156} 4156}
4157 4157
4158static s32
4159brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4160 const struct brcmf_event_msg *e, void *data)
4161{
4162 switch (e->reason) {
4163 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4164 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4165 break;
4166 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4167 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4168 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4169 break;
4170 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4171 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4172 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4173 break;
4174 }
4175
4176 return 0;
4177}
4178
4158static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper) 4179static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4159{ 4180{
4160 int ret; 4181 int ret;
@@ -5691,6 +5712,9 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5691 if (err) { 5712 if (err) {
5692 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err); 5713 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5693 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS; 5714 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5715 } else {
5716 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
5717 brcmf_notify_tdls_peer_event);
5694 } 5718 }
5695 5719
5696 return cfg; 5720 return cfg;