|
|
@@ -35,6 +35,7 @@
|
|
|
#include "wl_cfg80211.h"
|
|
|
#include "feature.h"
|
|
|
#include "fwil.h"
|
|
|
+#include "proto.h"
|
|
|
#include "vendor.h"
|
|
|
|
|
|
#define BRCMF_SCAN_IE_LEN_MAX 2048
|
|
|
@@ -493,6 +494,22 @@ brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
|
|
|
+{
|
|
|
+ struct net_device *ndev = wdev->netdev;
|
|
|
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
|
|
+
|
|
|
+ if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
|
|
|
+ (wdev->iftype == NL80211_IFTYPE_AP) ||
|
|
|
+ (wdev->iftype == NL80211_IFTYPE_P2P_GO))
|
|
|
+ brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
|
|
|
+ ADDR_DIRECT);
|
|
|
+ else
|
|
|
+ brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
|
|
|
+ ADDR_INDIRECT);
|
|
|
+}
|
|
|
+
|
|
|
static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
|
|
|
{
|
|
|
enum nl80211_iftype iftype;
|
|
|
@@ -512,6 +529,8 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
|
|
u32 *flags,
|
|
|
struct vif_params *params)
|
|
|
{
|
|
|
+ struct wireless_dev *wdev;
|
|
|
+
|
|
|
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
|
|
|
switch (type) {
|
|
|
case NL80211_IFTYPE_ADHOC:
|
|
|
@@ -525,7 +544,10 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
|
|
case NL80211_IFTYPE_P2P_CLIENT:
|
|
|
case NL80211_IFTYPE_P2P_GO:
|
|
|
case NL80211_IFTYPE_P2P_DEVICE:
|
|
|
- return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
|
|
|
+ wdev = brcmf_p2p_add_vif(wiphy, name, type, flags, params);
|
|
|
+ if (!IS_ERR(wdev))
|
|
|
+ brcmf_cfg80211_update_proto_addr_mode(wdev);
|
|
|
+ return wdev;
|
|
|
case NL80211_IFTYPE_UNSPECIFIED:
|
|
|
default:
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
@@ -720,6 +742,8 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
|
|
|
}
|
|
|
ndev->ieee80211_ptr->iftype = type;
|
|
|
|
|
|
+ brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
|
|
|
+
|
|
|
done:
|
|
|
brcmf_dbg(TRACE, "Exit\n");
|
|
|
|
|
|
@@ -4525,6 +4549,13 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
|
|
|
struct ieee80211_channel *chan;
|
|
|
s32 err = 0;
|
|
|
|
|
|
+ if ((e->event_code == BRCMF_E_DEAUTH) ||
|
|
|
+ (e->event_code == BRCMF_E_DEAUTH_IND) ||
|
|
|
+ (e->event_code == BRCMF_E_DISASSOC_IND) ||
|
|
|
+ ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
|
|
|
+ brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
|
|
|
+ }
|
|
|
+
|
|
|
if (brcmf_is_apmode(ifp->vif)) {
|
|
|
err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
|
|
|
} else if (brcmf_is_linkup(e)) {
|