diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2014-07-30 07:20:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-07-31 13:41:45 -0400 |
commit | 8851cce085dce026f14e9fc525acc71e4c9d305b (patch) | |
tree | 0e8e20595321bdc397024f8418791b80ab36f2f2 /drivers/net/wireless/brcm80211 | |
parent | 9374a2b514194acd4865f0183acd7c48c3b36b05 (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.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/proto.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/proto.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 33 |
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 | ||
340 | static void | ||
341 | brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx, | ||
342 | enum proto_addr_mode addr_mode) | ||
343 | { | ||
344 | } | ||
345 | |||
346 | static void | ||
347 | brcmf_proto_bcdc_delete_peer(struct brcmf_pub *drvr, int ifidx, | ||
348 | u8 peer[ETH_ALEN]) | ||
349 | { | ||
350 | } | ||
340 | 351 | ||
341 | int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) | 352 | int 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 | ||
55 | void brcmf_proto_detach(struct brcmf_pub *drvr) | 59 | void 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 | |||
20 | enum proto_addr_mode { | ||
21 | ADDR_INDIRECT = 0, | ||
22 | ADDR_DIRECT | ||
23 | }; | ||
24 | |||
25 | |||
19 | struct brcmf_proto { | 26 | struct 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 | } |
50 | static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx, | 61 | static 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 | } |
66 | static inline void | ||
67 | brcmf_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 | } | ||
72 | static inline void | ||
73 | brcmf_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 | ||
497 | static void | ||
498 | brcmf_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 | |||
496 | static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif) | 513 | static 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 | |||
723 | done: | 747 | done: |
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)) { |