aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2014-07-30 07:20:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-31 13:41:45 -0400
commit8851cce085dce026f14e9fc525acc71e4c9d305b (patch)
tree0e8e20595321bdc397024f8418791b80ab36f2f2 /drivers/net/wireless/brcm80211
parent9374a2b514194acd4865f0183acd7c48c3b36b05 (diff)
brcmfmac: Add protocol addressing mode and peer deletion API.
The soon to be added protocol msgbuf requires information about interface addressing mode and peer deletion. This patch adds the necessary APIs to proto, implements dummy functions in BCDC and adds calls to proto wherever necessary by wl_cfg80211. Reviewed-by: Arend Van Spriel <arend@broadcom.com> 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>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c33
4 files changed, 75 insertions, 3 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
index c229210d50ba..10b48c2c4b36 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -337,6 +337,17 @@ brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset,
337 return brcmf_bus_txdata(drvr->bus_if, pktbuf); 337 return brcmf_bus_txdata(drvr->bus_if, pktbuf);
338} 338}
339 339
340static void
341brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
342 enum proto_addr_mode addr_mode)
343{
344}
345
346static void
347brcmf_proto_bcdc_delete_peer(struct brcmf_pub *drvr, int ifidx,
348 u8 peer[ETH_ALEN])
349{
350}
340 351
341int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) 352int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
342{ 353{
@@ -356,6 +367,8 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
356 drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd; 367 drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
357 drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd; 368 drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
358 drvr->proto->txdata = brcmf_proto_bcdc_txdata; 369 drvr->proto->txdata = brcmf_proto_bcdc_txdata;
370 drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode;
371 drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
359 drvr->proto->pd = bcdc; 372 drvr->proto->pd = bcdc;
360 373
361 drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; 374 drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
index b6b464184946..d333ff8fcfff 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
@@ -30,6 +30,8 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
30{ 30{
31 struct brcmf_proto *proto; 31 struct brcmf_proto *proto;
32 32
33 brcmf_dbg(TRACE, "Enter\n");
34
33 proto = kzalloc(sizeof(*proto), GFP_ATOMIC); 35 proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
34 if (!proto) 36 if (!proto)
35 goto fail; 37 goto fail;
@@ -40,7 +42,9 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
40 goto fail; 42 goto fail;
41 43
42 if ((proto->txdata == NULL) || (proto->hdrpull == NULL) || 44 if ((proto->txdata == NULL) || (proto->hdrpull == NULL) ||
43 (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) { 45 (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) ||
46 (proto->configure_addr_mode == NULL) ||
47 (proto->delete_peer == NULL)) {
44 brcmf_err("Not all proto handlers have been installed\n"); 48 brcmf_err("Not all proto handlers have been installed\n");
45 goto fail; 49 goto fail;
46 } 50 }
@@ -54,6 +58,8 @@ fail:
54 58
55void brcmf_proto_detach(struct brcmf_pub *drvr) 59void brcmf_proto_detach(struct brcmf_pub *drvr)
56{ 60{
61 brcmf_dbg(TRACE, "Enter\n");
62
57 if (drvr->proto) { 63 if (drvr->proto) {
58 brcmf_proto_bcdc_detach(drvr); 64 brcmf_proto_bcdc_detach(drvr);
59 kfree(drvr->proto); 65 kfree(drvr->proto);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
index 482fb0ba4a30..55942e3561a3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
@@ -16,6 +16,13 @@
16#ifndef BRCMFMAC_PROTO_H 16#ifndef BRCMFMAC_PROTO_H
17#define BRCMFMAC_PROTO_H 17#define BRCMFMAC_PROTO_H
18 18
19
20enum proto_addr_mode {
21 ADDR_INDIRECT = 0,
22 ADDR_DIRECT
23};
24
25
19struct brcmf_proto { 26struct brcmf_proto {
20 int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, 27 int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
21 struct sk_buff *skb); 28 struct sk_buff *skb);
@@ -25,6 +32,10 @@ struct brcmf_proto {
25 uint len); 32 uint len);
26 int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset, 33 int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
27 struct sk_buff *skb); 34 struct sk_buff *skb);
35 void (*configure_addr_mode)(struct brcmf_pub *drvr, int ifidx,
36 enum proto_addr_mode addr_mode);
37 void (*delete_peer)(struct brcmf_pub *drvr, int ifidx,
38 u8 peer[ETH_ALEN]);
28 void *pd; 39 void *pd;
29}; 40};
30 41
@@ -48,10 +59,21 @@ static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
48 return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); 59 return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
49} 60}
50static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx, 61static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx,
51 u8 offset, struct sk_buff *skb) 62 u8 offset, struct sk_buff *skb)
52{ 63{
53 return drvr->proto->txdata(drvr, ifidx, offset, skb); 64 return drvr->proto->txdata(drvr, ifidx, offset, skb);
54} 65}
66static inline void
67brcmf_proto_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
68 enum proto_addr_mode addr_mode)
69{
70 drvr->proto->configure_addr_mode(drvr, ifidx, addr_mode);
71}
72static inline void
73brcmf_proto_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
74{
75 drvr->proto->delete_peer(drvr, ifidx, peer);
76}
55 77
56 78
57#endif /* BRCMFMAC_PROTO_H */ 79#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 48078a321716..a0e555a9f5f7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -35,6 +35,7 @@
35#include "wl_cfg80211.h" 35#include "wl_cfg80211.h"
36#include "feature.h" 36#include "feature.h"
37#include "fwil.h" 37#include "fwil.h"
38#include "proto.h"
38#include "vendor.h" 39#include "vendor.h"
39 40
40#define BRCMF_SCAN_IE_LEN_MAX 2048 41#define BRCMF_SCAN_IE_LEN_MAX 2048
@@ -493,6 +494,22 @@ brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
493 return err; 494 return err;
494} 495}
495 496
497static void
498brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
499{
500 struct net_device *ndev = wdev->netdev;
501 struct brcmf_if *ifp = netdev_priv(ndev);
502
503 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
504 (wdev->iftype == NL80211_IFTYPE_AP) ||
505 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
506 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
507 ADDR_DIRECT);
508 else
509 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
510 ADDR_INDIRECT);
511}
512
496static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif) 513static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
497{ 514{
498 enum nl80211_iftype iftype; 515 enum nl80211_iftype iftype;
@@ -512,6 +529,8 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
512 u32 *flags, 529 u32 *flags,
513 struct vif_params *params) 530 struct vif_params *params)
514{ 531{
532 struct wireless_dev *wdev;
533
515 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); 534 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
516 switch (type) { 535 switch (type) {
517 case NL80211_IFTYPE_ADHOC: 536 case NL80211_IFTYPE_ADHOC:
@@ -525,7 +544,10 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
525 case NL80211_IFTYPE_P2P_CLIENT: 544 case NL80211_IFTYPE_P2P_CLIENT:
526 case NL80211_IFTYPE_P2P_GO: 545 case NL80211_IFTYPE_P2P_GO:
527 case NL80211_IFTYPE_P2P_DEVICE: 546 case NL80211_IFTYPE_P2P_DEVICE:
528 return brcmf_p2p_add_vif(wiphy, name, type, flags, params); 547 wdev = brcmf_p2p_add_vif(wiphy, name, type, flags, params);
548 if (!IS_ERR(wdev))
549 brcmf_cfg80211_update_proto_addr_mode(wdev);
550 return wdev;
529 case NL80211_IFTYPE_UNSPECIFIED: 551 case NL80211_IFTYPE_UNSPECIFIED:
530 default: 552 default:
531 return ERR_PTR(-EINVAL); 553 return ERR_PTR(-EINVAL);
@@ -720,6 +742,8 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
720 } 742 }
721 ndev->ieee80211_ptr->iftype = type; 743 ndev->ieee80211_ptr->iftype = type;
722 744
745 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
746
723done: 747done:
724 brcmf_dbg(TRACE, "Exit\n"); 748 brcmf_dbg(TRACE, "Exit\n");
725 749
@@ -4525,6 +4549,13 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4525 struct ieee80211_channel *chan; 4549 struct ieee80211_channel *chan;
4526 s32 err = 0; 4550 s32 err = 0;
4527 4551
4552 if ((e->event_code == BRCMF_E_DEAUTH) ||
4553 (e->event_code == BRCMF_E_DEAUTH_IND) ||
4554 (e->event_code == BRCMF_E_DISASSOC_IND) ||
4555 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
4556 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4557 }
4558
4528 if (brcmf_is_apmode(ifp->vif)) { 4559 if (brcmf_is_apmode(ifp->vif)) {
4529 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); 4560 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4530 } else if (brcmf_is_linkup(e)) { 4561 } else if (brcmf_is_linkup(e)) {