Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / brcm80211 / brcmfmac / dhd_linux.c
index d37620e93e61961b9406989df323782ab7730e6d..763a84eba2164ca73a07923059f39c067a8717da 100644 (file)
@@ -323,13 +323,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
                /* Strip header, count, deliver upward */
                skb_pull(skb, ETH_HLEN);
 
-               /* Process special event packets and then discard them */
-               brcmf_fweh_process_skb(drvr, skb, &ifidx);
-
-               if (drvr->iflist[ifidx]) {
-                       ifp = drvr->iflist[ifidx];
-                       ifp->ndev->last_rx = jiffies;
-               }
+               /* Process special event packets */
+               brcmf_fweh_process_skb(drvr, skb);
 
                if (!(ifp->ndev->flags & IFF_UP)) {
                        brcmu_pkt_buf_free_skb(skb);
@@ -755,15 +750,23 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
                }
        }
 
-       /* Allocate netdev, including space for private structure */
-       ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
-       if (!ndev) {
-               brcmf_err("OOM - alloc_netdev\n");
-               return ERR_PTR(-ENOMEM);
+       if (!brcmf_p2p_enable && bssidx == 1) {
+               /* this is P2P_DEVICE interface */
+               brcmf_dbg(INFO, "allocate non-netdev interface\n");
+               ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
+       } else {
+               brcmf_dbg(INFO, "allocate netdev interface\n");
+               /* Allocate netdev, including space for private structure */
+               ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
+               if (!ndev) {
+                       brcmf_err("OOM - alloc_netdev\n");
+                       return ERR_PTR(-ENOMEM);
+               }
+
+               ifp = netdev_priv(ndev);
+               ifp->ndev = ndev;
        }
 
-       ifp = netdev_priv(ndev);
-       ifp->ndev = ndev;
        ifp->drvr = drvr;
        drvr->iflist[bssidx] = ifp;
        ifp->ifidx = ifidx;
@@ -775,7 +778,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
                memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
 
        brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
-                 current->pid, ifp->ndev->name, ifp->mac_addr);
+                 current->pid, name, ifp->mac_addr);
 
        return ifp;
 }
@@ -807,11 +810,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
                }
 
                unregister_netdev(ifp->ndev);
-               drvr->iflist[bssidx] = NULL;
                if (bssidx == 0)
                        brcmf_cfg80211_detach(drvr->config);
                free_netdev(ifp->ndev);
+       } else {
+               kfree(ifp);
        }
+       drvr->iflist[bssidx] = NULL;
 }
 
 int brcmf_attach(uint bus_hdrlen, struct device *dev)
@@ -982,8 +987,7 @@ void brcmf_detach(struct device *dev)
        if (drvr->prot)
                brcmf_proto_detach(drvr);
 
-       if (drvr->fws)
-               brcmf_fws_deinit(drvr);
+       brcmf_fws_deinit(drvr);
 
        brcmf_debugfs_detach(drvr);
        bus_if->drvr = NULL;