diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/flowring.c | 94 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/flowring.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fweh.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fweh.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/proto.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/proto.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 24 |
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 | ||
352 | static void | ||
353 | brcmf_proto_bcdc_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, | ||
354 | u8 peer[ETH_ALEN]) | ||
355 | { | ||
356 | } | ||
357 | |||
352 | int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) | 358 | int 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 | ||
52 | static bool | ||
53 | brcmf_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 | |||
52 | u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN], | 69 | u32 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 | |||
474 | void 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 | ||
43 | struct brcmf_flowring_tdls_entry { | ||
44 | u8 mac[ETH_ALEN]; | ||
45 | struct brcmf_flowring_tdls_entry *next; | ||
46 | }; | ||
47 | |||
43 | struct brcmf_flowring { | 48 | struct 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); |
71 | void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx, | 78 | void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx, |
72 | u8 peer[ETH_ALEN]); | 79 | u8 peer[ETH_ALEN]); |
80 | void 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 | ||
754 | static void | 754 | static void |
755 | brcmf_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 | |||
763 | static void | ||
755 | brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf) | 764 | brcmf_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 | } |
79 | static inline void | ||
80 | brcmf_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 | ||
4158 | static s32 | ||
4159 | brcmf_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 | |||
4158 | static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper) | 4179 | static 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; |