]> Git Repo - linux.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <[email protected]>
Mon, 18 Feb 2013 18:47:13 +0000 (13:47 -0500)
committerJohn W. Linville <[email protected]>
Mon, 18 Feb 2013 18:47:13 +0000 (13:47 -0500)
Conflicts:
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/ti/wlcore/sdio.c
drivers/net/wireless/ti/wlcore/spi.c

17 files changed:
1  2 
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/wil6210/wmi.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/ti/wlcore/wlcore_i.h
drivers/staging/wlan-ng/cfg80211.c
include/net/cfg80211.h
net/wireless/core.c
net/wireless/reg.c
net/wireless/sysfs.c

index faa752b95d5a5959339cd5d56f1c9f10798fdbcc,54150b6a39aeea25c55f2886e207244d2f96cc80..96ac433ba7f685ee454e3219bdea0e12879c3956
@@@ -1204,7 -1204,7 +1204,7 @@@ static u8 ath_rc_build_ht_caps(struct a
                        caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
                else if (sta->ht_cap.mcs.rx_mask[1])
                        caps |= WLAN_RC_DS_FLAG;
-               if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+               if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
                        caps |= WLAN_RC_40_FLAG;
                        if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
                                caps |= WLAN_RC_SGI_FLAG;
@@@ -1452,7 -1452,17 +1452,7 @@@ static void ath_rate_free(void *priv
  
  static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
  {
 -      struct ath_softc *sc = priv;
 -      struct ath_rate_priv *rate_priv;
 -
 -      rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
 -      if (!rate_priv) {
 -              ath_err(ath9k_hw_common(sc->sc_ah),
 -                      "Unable to allocate private rc structure\n");
 -              return NULL;
 -      }
 -
 -      return rate_priv;
 +      return kzalloc(sizeof(struct ath_rate_priv), gfp);
  }
  
  static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
index c8aca3d500892822ee568c526fab8efb1c5ec716,79d608caa90319642aaaf2a49bff4d42e597e231..0bb3b76b4b58c0c846a2fde77af14fcdffadf339
@@@ -338,7 -338,7 +338,7 @@@ static void wmi_evt_rx_mgmt(struct wil6
                if (bss) {
                        wil_dbg_wmi(wil, "Added BSS %pM\n",
                                    rx_mgmt_frame->bssid);
-                       cfg80211_put_bss(bss);
+                       cfg80211_put_bss(wiphy, bss);
                } else {
                        wil_err(wil, "cfg80211_inform_bss() failed\n");
                }
@@@ -587,9 -587,11 +587,9 @@@ void wmi_recv_cmd(struct wil6210_priv *
                evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event,
                                             event.wmi) + len, 4),
                              GFP_KERNEL);
 -              if (!evt) {
 -                      wil_err(wil, "kmalloc for WMI event (%d) failed\n",
 -                              len);
 +              if (!evt)
                        return;
 -              }
 +
                evt->event.hdr = hdr;
                cmd = (void *)&evt->event.wmi;
                wil_memcpy_fromio_32(cmd, src, len);
@@@ -836,8 -838,10 +836,8 @@@ int wmi_set_ie(struct wil6210_priv *wil
        int rc;
        u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len;
        struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL);
 -      if (!cmd) {
 -              wil_err(wil, "kmalloc(%d) failed\n", len);
 +      if (!cmd)
                return -ENOMEM;
 -      }
  
        cmd->mgmt_frm_type = type;
        /* BUG: FW API define ieLen as u8. Will fix FW */
index 14b8fdde69542fe54f8fd33aef11022e4bdfd65f,6e3846ca88be299afcebe2c817835e0a4dd8e365..c06cea88df0dbcaf55b7b9078810c71e0c5f8851
@@@ -26,6 -26,8 +26,8 @@@
  #include "dhd_bus.h"
  #include "dhd_proto.h"
  #include "dhd_dbg.h"
+ #include "fwil_types.h"
+ #include "p2p.h"
  #include "wl_cfg80211.h"
  #include "fwil.h"
  
@@@ -40,6 -42,12 +42,12 @@@ MODULE_LICENSE("Dual BSD/GPL")
  int brcmf_msg_level;
  module_param(brcmf_msg_level, int, 0);
  
+ /* P2P0 enable */
+ static int brcmf_p2p_enable;
+ #ifdef CONFIG_BRCMDBG
+ module_param_named(p2pon, brcmf_p2p_enable, int, 0);
+ MODULE_PARM_DESC(p2pon, "enable p2p management functionality");
+ #endif
  
  char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
  {
@@@ -70,9 -78,10 +78,10 @@@ static void _brcmf_set_multicast_list(s
        u32 buflen;
        s32 err;
  
-       brcmf_dbg(TRACE, "enter\n");
        ifp = container_of(work, struct brcmf_if, multicast_work);
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
        ndev = ifp->ndev;
  
        /* Determine initial value of allmulti flag */
@@@ -129,9 -138,10 +138,10 @@@ _brcmf_set_mac_address(struct work_stru
        struct brcmf_if *ifp;
        s32 err;
  
-       brcmf_dbg(TRACE, "enter\n");
        ifp = container_of(work, struct brcmf_if, setmacaddr_work);
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
        err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
                                       ETH_ALEN);
        if (err < 0) {
@@@ -168,7 -178,7 +178,7 @@@ static netdev_tx_t brcmf_netdev_start_x
        struct brcmf_pub *drvr = ifp->drvr;
        struct ethhdr *eh;
  
-       brcmf_dbg(TRACE, "Enter\n");
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
  
        /* Can the device send data? */
        if (drvr->bus_if->state != BRCMF_BUS_DATA) {
                goto done;
        }
  
-       if (!drvr->iflist[ifp->idx]) {
-               brcmf_err("bad ifidx %d\n", ifp->idx);
+       if (!drvr->iflist[ifp->bssidx]) {
+               brcmf_err("bad ifidx %d\n", ifp->bssidx);
                netif_stop_queue(ndev);
                dev_kfree_skb(skb);
                ret = -ENODEV;
                struct sk_buff *skb2;
  
                brcmf_dbg(INFO, "%s: insufficient headroom\n",
-                         brcmf_ifname(drvr, ifp->idx));
+                         brcmf_ifname(drvr, ifp->bssidx));
                drvr->bus_if->tx_realloc++;
                skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
                dev_kfree_skb(skb);
                skb = skb2;
                if (skb == NULL) {
                        brcmf_err("%s: skb_realloc_headroom failed\n",
-                                 brcmf_ifname(drvr, ifp->idx));
+                                 brcmf_ifname(drvr, ifp->bssidx));
                        ret = -ENOMEM;
                        goto done;
                }
        if (is_multicast_ether_addr(eh->h_dest))
                drvr->tx_multicast++;
        if (ntohs(eh->h_proto) == ETH_P_PAE)
-               atomic_inc(&drvr->pend_8021x_cnt);
+               atomic_inc(&ifp->pend_8021x_cnt);
  
        /* If the protocol uses a data header, apply it */
-       brcmf_proto_hdrpush(drvr, ifp->idx, skb);
+       brcmf_proto_hdrpush(drvr, ifp->ifidx, skb);
  
        /* Use bus module to send data frame */
        ret =  brcmf_bus_txdata(drvr->bus_if, skb);
  
  done:
-       if (ret)
-               drvr->bus_if->dstats.tx_dropped++;
-       else
-               drvr->bus_if->dstats.tx_packets++;
+       if (ret) {
+               ifp->stats.tx_dropped++;
+       } else {
+               ifp->stats.tx_packets++;
+               ifp->stats.tx_bytes += skb->len;
+       }
  
        /* Return ok: we always eat the packet */
        return NETDEV_TX_OK;
@@@ -270,12 -282,13 +282,13 @@@ void brcmf_rx_frames(struct device *dev
        skb_queue_walk_safe(skb_list, skb, pnext) {
                skb_unlink(skb, skb_list);
  
-               /* process and remove protocol-specific header
-                */
+               /* process and remove protocol-specific header */
                ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
-               if (ret < 0) {
-                       if (ret != -ENODATA)
-                               bus_if->dstats.rx_errors++;
+               ifp = drvr->iflist[ifidx];
+               if (ret || !ifp || !ifp->ndev) {
+                       if ((ret != -ENODATA) && ifp)
+                               ifp->stats.rx_errors++;
                        brcmu_pkt_buf_free_skb(skb);
                        continue;
                }
                eth = skb->data;
                len = skb->len;
  
-               ifp = drvr->iflist[ifidx];
-               if (ifp == NULL)
-                       ifp = drvr->iflist[0];
-               if (!ifp || !ifp->ndev ||
-                   ifp->ndev->reg_state != NETREG_REGISTERED) {
-                       brcmu_pkt_buf_free_skb(skb);
-                       continue;
-               }
                skb->dev = ifp->ndev;
                skb->protocol = eth_type_trans(skb, skb->dev);
  
                if (skb->pkt_type == PACKET_MULTICAST)
-                       bus_if->dstats.multicast++;
+                       ifp->stats.multicast++;
  
                skb->data = eth;
                skb->len = len;
                        ifp->ndev->last_rx = jiffies;
                }
  
-               bus_if->dstats.rx_bytes += skb->len;
-               bus_if->dstats.rx_packets++;    /* Local count */
+               if (!(ifp->ndev->flags & IFF_UP)) {
+                       brcmu_pkt_buf_free_skb(skb);
+                       continue;
+               }
+               ifp->stats.rx_bytes += skb->len;
+               ifp->stats.rx_packets++;
  
                if (in_interrupt())
                        netif_rx(skb);
@@@ -348,36 -356,31 +356,31 @@@ void brcmf_txcomplete(struct device *de
        u16 type;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
        struct brcmf_pub *drvr = bus_if->drvr;
+       struct brcmf_if *ifp;
  
        brcmf_proto_hdrpull(drvr, &ifidx, txp);
  
+       ifp = drvr->iflist[ifidx];
+       if (!ifp)
+               return;
        eh = (struct ethhdr *)(txp->data);
        type = ntohs(eh->h_proto);
  
        if (type == ETH_P_PAE) {
-               atomic_dec(&drvr->pend_8021x_cnt);
-               if (waitqueue_active(&drvr->pend_8021x_wait))
-                       wake_up(&drvr->pend_8021x_wait);
+               atomic_dec(&ifp->pend_8021x_cnt);
+               if (waitqueue_active(&ifp->pend_8021x_wait))
+                       wake_up(&ifp->pend_8021x_wait);
        }
+       if (!success)
+               ifp->stats.tx_errors++;
  }
  
  static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
  {
        struct brcmf_if *ifp = netdev_priv(ndev);
-       struct brcmf_bus *bus_if = ifp->drvr->bus_if;
-       brcmf_dbg(TRACE, "Enter\n");
  
-       /* Copy dongle stats to net device stats */
-       ifp->stats.rx_packets = bus_if->dstats.rx_packets;
-       ifp->stats.tx_packets = bus_if->dstats.tx_packets;
-       ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
-       ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
-       ifp->stats.rx_errors = bus_if->dstats.rx_errors;
-       ifp->stats.tx_errors = bus_if->dstats.tx_errors;
-       ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
-       ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
-       ifp->stats.multicast = bus_if->dstats.multicast;
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
  
        return &ifp->stats;
  }
@@@ -410,11 -413,9 +413,11 @@@ static void brcmf_ethtool_get_drvinfo(s
        struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_pub *drvr = ifp->drvr;
  
 -      sprintf(info->driver, KBUILD_MODNAME);
 -      sprintf(info->version, "%lu", drvr->drv_version);
 -      sprintf(info->bus_info, "%s", dev_name(drvr->bus_if->dev));
 +      strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
 +      snprintf(info->version, sizeof(info->version), "%lu",
 +               drvr->drv_version);
 +      strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
 +              sizeof(info->bus_info));
  }
  
  static const struct ethtool_ops brcmf_ethtool_ops = {
@@@ -431,7 -432,7 +434,7 @@@ static int brcmf_ethtool(struct brcmf_i
        u32 toe_cmpnt, csum_dir;
        int ret;
  
-       brcmf_dbg(TRACE, "Enter\n");
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
  
        /* all ethtool calls start with a cmd word */
        if (copy_from_user(&cmd, uaddr, sizeof(u32)))
                        sprintf(info.driver, "dhd");
                        strcpy(info.version, BRCMF_VERSION_STR);
                }
-               /* otherwise, require dongle to be up */
-               else if (!drvr->bus_if->drvr_up) {
-                       brcmf_err("dongle is not up\n");
-                       return -ENODEV;
-               }
-               /* finally, report dongle driver type */
+               /* report dongle driver type */
                else
                        sprintf(info.driver, "wl");
  
@@@ -534,9 -529,9 +531,9 @@@ static int brcmf_netdev_ioctl_entry(str
        struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_pub *drvr = ifp->drvr;
  
-       brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd);
+       brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
  
-       if (!drvr->iflist[ifp->idx])
+       if (!drvr->iflist[ifp->bssidx])
                return -1;
  
        if (cmd == SIOCETHTOOL)
  static int brcmf_netdev_stop(struct net_device *ndev)
  {
        struct brcmf_if *ifp = netdev_priv(ndev);
-       struct brcmf_pub *drvr = ifp->drvr;
-       brcmf_dbg(TRACE, "Enter\n");
  
-       if (drvr->bus_if->drvr_up == 0)
-               return 0;
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
  
        brcmf_cfg80211_down(ndev);
  
        /* Set state and stop OS transmissions */
-       drvr->bus_if->drvr_up = false;
        netif_stop_queue(ndev);
  
        return 0;
@@@ -572,7 -562,7 +564,7 @@@ static int brcmf_netdev_open(struct net
        u32 toe_ol;
        s32 ret = 0;
  
-       brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
+       brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
  
        /* If bus is not ready, can't continue */
        if (bus_if->state != BRCMF_BUS_DATA) {
                return -EAGAIN;
        }
  
-       atomic_set(&drvr->pend_8021x_cnt, 0);
-       memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
+       atomic_set(&ifp->pend_8021x_cnt, 0);
  
        /* Get current TOE mode from dongle */
        if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
  
        /* Allow transmit calls */
        netif_start_queue(ndev);
-       drvr->bus_if->drvr_up = true;
        if (brcmf_cfg80211_up(ndev)) {
                brcmf_err("failed to bring up cfg80211\n");
                return -1;
@@@ -612,29 -599,18 +601,18 @@@ static const struct net_device_ops brcm
        .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
  };
  
- static const struct net_device_ops brcmf_netdev_ops_virt = {
-       .ndo_open = brcmf_cfg80211_up,
-       .ndo_stop = brcmf_cfg80211_down,
-       .ndo_get_stats = brcmf_netdev_get_stats,
-       .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
-       .ndo_start_xmit = brcmf_netdev_start_xmit,
-       .ndo_set_mac_address = brcmf_netdev_set_mac_address,
-       .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
- };
- int brcmf_net_attach(struct brcmf_if *ifp)
+ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
  {
        struct brcmf_pub *drvr = ifp->drvr;
        struct net_device *ndev;
+       s32 err;
  
-       brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr);
+       brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
+                 ifp->mac_addr);
        ndev = ifp->ndev;
  
        /* set appropriate operations */
-       if (!ifp->idx)
-               ndev->netdev_ops = &brcmf_netdev_ops_pri;
-       else
-               ndev->netdev_ops = &brcmf_netdev_ops_virt;
+       ndev->netdev_ops = &brcmf_netdev_ops_pri;
  
        ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
        ndev->ethtool_ops = &brcmf_ethtool_ops;
        /* set the mac address */
        memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
  
-       if (register_netdev(ndev) != 0) {
+       INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
+       INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
+       if (rtnl_locked)
+               err = register_netdevice(ndev);
+       else
+               err = register_netdev(ndev);
+       if (err != 0) {
                brcmf_err("couldn't register the net device\n");
                goto fail;
        }
@@@ -659,16 -642,78 +644,78 @@@ fail
        return -EBADE;
  }
  
- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
-                             char *name, u8 *addr_mask)
+ static int brcmf_net_p2p_open(struct net_device *ndev)
+ {
+       brcmf_dbg(TRACE, "Enter\n");
+       return brcmf_cfg80211_up(ndev);
+ }
+ static int brcmf_net_p2p_stop(struct net_device *ndev)
+ {
+       brcmf_dbg(TRACE, "Enter\n");
+       return brcmf_cfg80211_down(ndev);
+ }
+ static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
+                                 struct ifreq *ifr, int cmd)
+ {
+       brcmf_dbg(TRACE, "Enter\n");
+       return 0;
+ }
+ static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
+                                           struct net_device *ndev)
+ {
+       if (skb)
+               dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+ }
+ static const struct net_device_ops brcmf_netdev_ops_p2p = {
+       .ndo_open = brcmf_net_p2p_open,
+       .ndo_stop = brcmf_net_p2p_stop,
+       .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
+       .ndo_start_xmit = brcmf_net_p2p_start_xmit
+ };
+ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
+ {
+       struct net_device *ndev;
+       brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
+                 ifp->mac_addr);
+       ndev = ifp->ndev;
+       ndev->netdev_ops = &brcmf_netdev_ops_p2p;
+       /* set the mac address */
+       memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
+       if (register_netdev(ndev) != 0) {
+               brcmf_err("couldn't register the p2p net device\n");
+               goto fail;
+       }
+       brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
+       return 0;
+ fail:
+       return -EBADE;
+ }
+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
+                             char *name, u8 *mac_addr)
  {
        struct brcmf_if *ifp;
        struct net_device *ndev;
-       int i;
  
-       brcmf_dbg(TRACE, "idx %d\n", ifidx);
+       brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifidx);
  
-       ifp = drvr->iflist[ifidx];
+       ifp = drvr->iflist[bssidx];
        /*
         * Delete the existing interface before overwriting it
         * in case we missed the BRCMF_E_IF_DEL event.
                        netif_stop_queue(ifp->ndev);
                        unregister_netdev(ifp->ndev);
                        free_netdev(ifp->ndev);
-                       drvr->iflist[ifidx] = NULL;
+                       drvr->iflist[bssidx] = NULL;
                } else {
                        brcmf_err("ignore IF event\n");
                        return ERR_PTR(-EINVAL);
        ifp = netdev_priv(ndev);
        ifp->ndev = ndev;
        ifp->drvr = drvr;
-       drvr->iflist[ifidx] = ifp;
-       ifp->idx = ifidx;
+       drvr->iflist[bssidx] = ifp;
+       ifp->ifidx = ifidx;
        ifp->bssidx = bssidx;
  
-       INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
-       INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
  
-       if (addr_mask != NULL)
-               for (i = 0; i < ETH_ALEN; i++)
-                       ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i];
+       init_waitqueue_head(&ifp->pend_8021x_wait);
+       if (mac_addr != NULL)
+               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);
        return ifp;
  }
  
- void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
+ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
  {
        struct brcmf_if *ifp;
  
-       brcmf_dbg(TRACE, "idx %d\n", ifidx);
-       ifp = drvr->iflist[ifidx];
+       ifp = drvr->iflist[bssidx];
        if (!ifp) {
-               brcmf_err("Null interface\n");
+               brcmf_err("Null interface, idx=%d\n", bssidx);
                return;
        }
+       brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
        if (ifp->ndev) {
-               if (ifidx == 0) {
+               if (bssidx == 0) {
                        if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
                                rtnl_lock();
                                brcmf_netdev_stop(ifp->ndev);
                        netif_stop_queue(ifp->ndev);
                }
  
-               cancel_work_sync(&ifp->setmacaddr_work);
-               cancel_work_sync(&ifp->multicast_work);
+               if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
+                       cancel_work_sync(&ifp->setmacaddr_work);
+                       cancel_work_sync(&ifp->multicast_work);
+               }
  
                unregister_netdev(ifp->ndev);
-               drvr->iflist[ifidx] = NULL;
-               if (ifidx == 0)
+               drvr->iflist[bssidx] = NULL;
+               if (bssidx == 0)
                        brcmf_cfg80211_detach(drvr->config);
                free_netdev(ifp->ndev);
        }
@@@ -781,8 -826,6 +828,6 @@@ int brcmf_attach(uint bus_hdrlen, struc
  
        INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
  
-       init_waitqueue_head(&drvr->pend_8021x_wait);
        return ret;
  
  fail:
@@@ -797,6 -840,7 +842,7 @@@ int brcmf_bus_start(struct device *dev
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
        struct brcmf_pub *drvr = bus_if->drvr;
        struct brcmf_if *ifp;
+       struct brcmf_if *p2p_ifp;
  
        brcmf_dbg(TRACE, "\n");
  
        if (IS_ERR(ifp))
                return PTR_ERR(ifp);
  
+       if (brcmf_p2p_enable)
+               p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
+       else
+               p2p_ifp = NULL;
+       if (IS_ERR(p2p_ifp))
+               p2p_ifp = NULL;
        /* signal bus ready */
        bus_if->state = BRCMF_BUS_DATA;
  
        if (ret < 0)
                goto fail;
  
-       ret = brcmf_net_attach(ifp);
+       ret = brcmf_net_attach(ifp, false);
  fail:
        if (ret < 0) {
                brcmf_err("failed: %d\n", ret);
                if (drvr->config)
                        brcmf_cfg80211_detach(drvr->config);
-               free_netdev(drvr->iflist[0]->ndev);
+               free_netdev(ifp->ndev);
                drvr->iflist[0] = NULL;
+               if (p2p_ifp) {
+                       free_netdev(p2p_ifp->ndev);
+                       drvr->iflist[1] = NULL;
+               }
                return ret;
        }
+       if ((brcmf_p2p_enable) && (p2p_ifp))
+               brcmf_net_p2p_attach(p2p_ifp);
  
        return 0;
  }
@@@ -865,12 -922,13 +924,13 @@@ void brcmf_dev_reset(struct device *dev
        if (drvr == NULL)
                return;
  
-       brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
+       if (drvr->iflist[0])
+               brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
  }
  
  void brcmf_detach(struct device *dev)
  {
-       int i;
+       s32 i;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
        struct brcmf_pub *drvr = bus_if->drvr;
  
        kfree(drvr);
  }
  
- static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
+ static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
  {
-       return atomic_read(&drvr->pend_8021x_cnt);
+       return atomic_read(&ifp->pend_8021x_cnt);
  }
  
  int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
  {
        struct brcmf_if *ifp = netdev_priv(ndev);
-       struct brcmf_pub *drvr = ifp->drvr;
        int err;
  
-       err = wait_event_timeout(drvr->pend_8021x_wait,
-                                !brcmf_get_pend_8021x_cnt(drvr),
+       err = wait_event_timeout(ifp->pend_8021x_wait,
+                                !brcmf_get_pend_8021x_cnt(ifp),
                                 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
  
        WARN_ON(!err);
        return !err;
  }
  
+ /*
+  * return chip id and rev of the device encoded in u32.
+  */
+ u32 brcmf_get_chip_info(struct brcmf_if *ifp)
+ {
+       struct brcmf_bus *bus = ifp->drvr->bus_if;
+       return bus->chip << 4 | bus->chiprev;
+ }
  static void brcmf_driver_init(struct work_struct *work)
  {
        brcmf_debugfs_init();
index 6d786a281f1e2fb4a45b7047a689af3469f2964b,35817631ea0637271ddd40fb475c14f58ac30be8..4469321c0eb3ea3924f68b02ff6863516ec9b333
@@@ -1096,7 -1096,6 +1096,6 @@@ static int brcmf_sdio_hdparser(struct b
        if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
            type != BRCMF_SDIO_FT_SUPER) {
                brcmf_err("HW header length too long\n");
-               bus->sdiodev->bus_if->dstats.rx_errors++;
                bus->sdcnt.rx_toolong++;
                brcmf_sdbrcm_rxfail(bus, false, false);
                rd->len = 0;
@@@ -1298,7 -1297,6 +1297,6 @@@ static u8 brcmf_sdbrcm_rxglom(struct br
                if (errcode < 0) {
                        brcmf_err("glom read of %d bytes failed: %d\n",
                                  dlen, errcode);
-                       bus->sdiodev->bus_if->dstats.rx_errors++;
  
                        sdio_claim_host(bus->sdiodev->func[1]);
                        if (bus->glomerr++ < 3) {
@@@ -1445,9 -1443,10 +1443,9 @@@ brcmf_sdbrcm_read_control(struct brcmf_
  
        if (bus->rxblen)
                buf = vzalloc(bus->rxblen);
 -      if (!buf) {
 -              brcmf_err("no memory for control frame\n");
 +      if (!buf)
                goto done;
 -      }
 +
        rbuf = bus->rxbuf;
        pad = ((unsigned long)rbuf % BRCMF_SDALIGN);
        if (pad)
        if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
                brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
                          rdlen, bus->sdiodev->bus_if->maxctl);
-               bus->sdiodev->bus_if->dstats.rx_errors++;
                brcmf_sdbrcm_rxfail(bus, false, false);
                goto done;
        }
        if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
                brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
                          len, len - doff, bus->sdiodev->bus_if->maxctl);
-               bus->sdiodev->bus_if->dstats.rx_errors++;
                bus->sdcnt.rx_toolong++;
                brcmf_sdbrcm_rxfail(bus, false, false);
                goto done;
@@@ -1633,7 -1630,6 +1629,6 @@@ static uint brcmf_sdio_readframes(struc
                if (!pkt) {
                        /* Give up on data, request rtx of events */
                        brcmf_err("brcmu_pkt_buf_get_skb failed\n");
-                       bus->sdiodev->bus_if->dstats.rx_dropped++;
                        brcmf_sdbrcm_rxfail(bus, false,
                                            RETRYCHAN(rd->channel));
                        sdio_release_host(bus->sdiodev->func[1]);
                        brcmf_err("read %d bytes from channel %d failed: %d\n",
                                  rd->len, rd->channel, sdret);
                        brcmu_pkt_buf_free_skb(pkt);
-                       bus->sdiodev->bus_if->dstats.rx_errors++;
                        sdio_claim_host(bus->sdiodev->func[1]);
                        brcmf_sdbrcm_rxfail(bus, true,
                                            RETRYCHAN(rd->channel));
@@@ -1939,10 -1934,6 +1933,6 @@@ static uint brcmf_sdbrcm_sendfromq(stru
                datalen = pkt->len - SDPCM_HDRLEN;
  
                ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
-               if (ret)
-                       bus->sdiodev->bus_if->dstats.tx_errors++;
-               else
-                       bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
  
                /* In poll mode, need to check for other events */
                if (!bus->intr && cnt) {
        }
  
        /* Deflow-control stack if needed */
-       if (bus->sdiodev->bus_if->drvr_up &&
-           (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
+       if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
            bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
                bus->txoff = false;
                brcmf_txflowblock(bus->sdiodev->dev, false);
@@@ -2709,9 -2699,10 +2698,10 @@@ static int brcmf_sdio_readshared(struc
         * address of sdpcm_shared structure
         */
        sdio_claim_host(bus->sdiodev->func[1]);
+       brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
        rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
                                   (u8 *)&addr_le, 4);
-       sdio_claim_host(bus->sdiodev->func[1]);
+       sdio_release_host(bus->sdiodev->func[1]);
        if (rv < 0)
                return rv;
  
        }
  
        /* Read hndrte_shared structure */
-       sdio_claim_host(bus->sdiodev->func[1]);
        rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
                                   sizeof(struct sdpcm_shared_le));
-       sdio_release_host(bus->sdiodev->func[1]);
        if (rv < 0)
                return rv;
  
@@@ -2835,14 -2824,12 +2823,12 @@@ static int brcmf_sdio_trap_info(struct 
        if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
                return 0;
  
-       sdio_claim_host(bus->sdiodev->func[1]);
        error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
                                      sizeof(struct brcmf_trap_info));
        if (error < 0)
                return error;
  
        nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
-       sdio_release_host(bus->sdiodev->func[1]);
        if (nbytes < 0)
                return nbytes;
  
@@@ -3307,9 -3294,6 +3293,6 @@@ static int brcmf_sdbrcm_download_nvram(
  {
        int ret;
  
-       if (bus->sdiodev->bus_if->drvr_up)
-               return -EISCONN;
        ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
                               &bus->sdiodev->func[2]->dev);
        if (ret) {
@@@ -3940,6 -3924,8 +3923,8 @@@ void *brcmf_sdbrcm_probe(u32 regsva, st
        /* Assign bus interface call back */
        bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
        bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops;
+       bus->sdiodev->bus_if->chip = bus->ci->chip;
+       bus->sdiodev->bus_if->chiprev = bus->ci->chiprev;
  
        /* Attach to the brcmf/OS/network interface */
        ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
index bc5a042c9a96aa3e25b61a046fe8610b92d5135f,a55994d337630a1fa5758675a0119d5f733acf7c..42289e9ea8863d0bee3d04a78dbcdf0e46d17c5d
@@@ -354,10 -354,11 +354,10 @@@ brcmf_usbdev_qinit(struct list_head *q
        int i;
        struct brcmf_usbreq *req, *reqs;
  
 -      reqs = kzalloc(sizeof(struct brcmf_usbreq) * qsize, GFP_ATOMIC);
 -      if (reqs == NULL) {
 -              brcmf_err("fail to allocate memory!\n");
 +      reqs = kcalloc(qsize, sizeof(struct brcmf_usbreq), GFP_ATOMIC);
 +      if (reqs == NULL)
                return NULL;
 -      }
 +
        req = reqs;
  
        for (i = 0; i < qsize; i++) {
@@@ -420,10 -421,6 +420,6 @@@ static void brcmf_usb_tx_complete(struc
        brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
                  req->skb);
        brcmf_usb_del_fromq(devinfo, req);
-       if (urb->status == 0)
-               devinfo->bus_pub.bus->dstats.tx_packets++;
-       else
-               devinfo->bus_pub.bus->dstats.tx_errors++;
  
        brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
  
@@@ -450,10 -447,7 +446,7 @@@ static void brcmf_usb_rx_complete(struc
        req->skb = NULL;
  
        /* zero lenght packets indicate usb "failure". Do not refill */
-       if (urb->status == 0 && urb->actual_length) {
-               devinfo->bus_pub.bus->dstats.rx_packets++;
-       } else {
-               devinfo->bus_pub.bus->dstats.rx_errors++;
+       if (urb->status != 0 || !urb->actual_length) {
                brcmu_pkt_buf_free_skb(skb);
                brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
                return;
@@@ -1256,6 -1250,8 +1249,8 @@@ static int brcmf_usb_probe_cb(struct br
        bus->bus_priv.usb = bus_pub;
        dev_set_drvdata(dev, bus);
        bus->ops = &brcmf_usb_bus_ops;
+       bus->chip = bus_pub->devid;
+       bus->chiprev = bus_pub->chiprev;
  
        /* Attach to the common driver interface */
        ret = brcmf_attach(0, dev);
index a7dcb2e5eccc0120c0901fbf8b75b70650326f70,61735db3b0515684a82983c713c4bd4120242fbe..116f4aba08d6f629275b3c29a0b98869191e1334
@@@ -657,7 -657,7 +657,7 @@@ static int lbs_ret_scan(struct lbs_priv
                                        capa, intvl, ie, ielen,
                                        LBS_SCAN_RSSI_TO_MBM(rssi),
                                        GFP_KERNEL);
-                               cfg80211_put_bss(bss);
+                               cfg80211_put_bss(wiphy, bss);
                        }
                } else
                        lbs_deb_scan("scan response: missing BSS channel IE\n");
@@@ -1444,7 -1444,7 +1444,7 @@@ static int lbs_cfg_connect(struct wiph
  
   done:
        if (bss)
-               cfg80211_put_bss(bss);
+               cfg80211_put_bss(wiphy, bss);
        lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
        return ret;
  }
@@@ -1766,7 -1766,7 +1766,7 @@@ static void lbs_join_post(struct lbs_pr
                                  params->beacon_interval,
                                  fake_ie, fake - fake_ie,
                                  0, GFP_KERNEL);
-       cfg80211_put_bss(bss);
+       cfg80211_put_bss(priv->wdev->wiphy, bss);
  
        memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
        priv->wdev->ssid_len = params->ssid_len;
@@@ -2011,7 -2011,7 +2011,7 @@@ static int lbs_join_ibss(struct wiphy *
  
        if (bss) {
                ret = lbs_ibss_join_existing(priv, params, bss);
-               cfg80211_put_bss(bss);
+               cfg80211_put_bss(wiphy, bss);
        } else
                ret = lbs_ibss_start_new(priv, params);
  
@@@ -2081,8 -2081,10 +2081,8 @@@ struct wireless_dev *lbs_cfg_alloc(stru
        lbs_deb_enter(LBS_DEB_CFG80211);
  
        wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
 -      if (!wdev) {
 -              dev_err(dev, "cannot allocate wireless device\n");
 +      if (!wdev)
                return ERR_PTR(-ENOMEM);
 -      }
  
        wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private));
        if (!wdev->wiphy) {
index 8ba48192cd2fb937cbfe46807e1cea7c97487272,81c84a29308f9d93ffac48243bcd39b939949ce3..dc5357c0098f8046241038715a68f4a84ad61ec4
@@@ -1430,7 -1430,7 +1430,7 @@@ static int mwifiex_cfg80211_inform_ibss
        bss = cfg80211_inform_bss(priv->wdev->wiphy, chan,
                                  bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
                                  0, ie_buf, ie_len, 0, GFP_KERNEL);
-       cfg80211_put_bss(bss);
+       cfg80211_put_bss(priv->wdev->wiphy, bss);
        memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
  
        return 0;
@@@ -1820,8 -1820,10 +1820,8 @@@ mwifiex_cfg80211_scan(struct wiphy *wip
  
        priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
                                      GFP_KERNEL);
 -      if (!priv->user_scan_cfg) {
 -              dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
 +      if (!priv->user_scan_cfg)
                return -ENOMEM;
 -      }
  
        priv->scan_request = request;
  
@@@ -2101,6 -2103,7 +2101,6 @@@ struct wireless_dev *mwifiex_add_virtua
        dev->ieee80211_ptr = priv->wdev;
        dev->ieee80211_ptr->iftype = priv->bss_mode;
        memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
 -      memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
        SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
  
        dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
index d41f0e6472808fe822cbdee97dc80947ca0e040f,949234fcf8c64b23e0a922b54c33564fc199d068..e0cce1b52d55635e550e926b17be7814565f5cd7
@@@ -1309,6 -1309,7 +1309,6 @@@ int mwifiex_scan_networks(struct mwifie
        struct cmd_ctrl_node *cmd_node;
        union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
        struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
 -      u32 buf_size;
        struct mwifiex_chan_scan_param_set *scan_chan_list;
        u8 filtered_scan;
        u8 scan_current_chan_only;
        spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
  
        scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
 -                                                              GFP_KERNEL);
 +                             GFP_KERNEL);
        if (!scan_cfg_out) {
 -              dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
                ret = -ENOMEM;
                goto done;
        }
  
 -      buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
 -                                              MWIFIEX_USER_SCAN_CHAN_MAX;
 -      scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
 +      scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX,
 +                               sizeof(struct mwifiex_chan_scan_param_set),
 +                               GFP_KERNEL);
        if (!scan_chan_list) {
 -              dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
                kfree(scan_cfg_out);
                ret = -ENOMEM;
                goto done;
@@@ -1458,9 -1461,12 +1458,9 @@@ static int mwifiex_update_curr_bss_para
        unsigned long flags;
  
        /* Allocate and fill new bss descriptor */
 -      bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
 -                      GFP_KERNEL);
 -      if (!bss_desc) {
 -              dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
 +      bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL);
 +      if (!bss_desc)
                return -ENOMEM;
 -      }
  
        ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
        if (ret)
@@@ -1741,7 -1747,7 +1741,7 @@@ int mwifiex_ret_802_11_scan(struct mwif
                                            .mac_address, ETH_ALEN))
                                        mwifiex_update_curr_bss_params(priv,
                                                                       bss);
-                               cfg80211_put_bss(bss);
+                               cfg80211_put_bss(priv->wdev->wiphy, bss);
                        }
                } else {
                        dev_dbg(adapter->dev, "missing BSS channel IE\n");
@@@ -1874,8 -1880,10 +1874,8 @@@ static int mwifiex_scan_specific_ssid(s
        }
  
        scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
 -      if (!scan_cfg) {
 -              dev_err(adapter->dev, "failed to alloc scan_cfg\n");
 +      if (!scan_cfg)
                return -ENOMEM;
 -      }
  
        scan_cfg->ssid_list = req_ssid;
        scan_cfg->num_ssids = 1;
@@@ -1989,8 -1997,11 +1989,8 @@@ mwifiex_save_curr_bcn(struct mwifiex_pr
                kfree(priv->curr_bcn_buf);
                priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
                                             GFP_ATOMIC);
 -              if (!priv->curr_bcn_buf) {
 -                      dev_err(priv->adapter->dev,
 -                              "failed to alloc curr_bcn_buf\n");
 +              if (!priv->curr_bcn_buf)
                        return;
 -              }
        }
  
        memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
index b8fa76a2b953992c69c7141f31a50cf636ca0a09,0d018460daf9eff917d4238f5b712363221b2285..7eef74564a92f50a308c5d54d54ce02d0cdb430a
@@@ -162,13 -162,9 +162,9 @@@ int mwifiex_fill_new_bss_desc(struct mw
  
        rcu_read_lock();
        ies = rcu_dereference(bss->ies);
-       if (WARN_ON(!ies)) {
-               /* should never happen */
-               rcu_read_unlock();
-               return -EINVAL;
-       }
        beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC);
        beacon_ie_len = ies->len;
+       bss_desc->timestamp = ies->tsf;
        rcu_read_unlock();
  
        if (!beacon_ie) {
        bss_desc->cap_info_bitmap = bss->capability;
        bss_desc->bss_band = bss_priv->band;
        bss_desc->fw_tsf = bss_priv->fw_tsf;
-       bss_desc->timestamp = bss->tsf;
        if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
                dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
                bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
@@@ -266,9 -261,11 +261,9 @@@ int mwifiex_bss_start(struct mwifiex_pr
  
                /* Allocate and fill new bss descriptor */
                bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
 -                              GFP_KERNEL);
 -              if (!bss_desc) {
 -                      dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
 +                                 GFP_KERNEL);
 +              if (!bss_desc)
                        return -ENOMEM;
 -              }
  
                ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
                if (ret)
                }
  
                if (bss)
-                       cfg80211_put_bss(bss);
+                       cfg80211_put_bss(priv->adapter->wiphy, bss);
        } else {
                /* Adhoc mode */
                /* If the requested SSID matches current SSID, return */
                                                        " list. Joining...\n");
                        ret = mwifiex_adhoc_join(priv, bss_desc);
                        if (bss)
-                               cfg80211_put_bss(bss);
+                               cfg80211_put_bss(priv->adapter->wiphy, bss);
                } else {
                        dev_dbg(adapter->dev, "info: Network not found in "
                                "the list, creating adhoc with ssid = %s\n",
@@@ -634,8 -631,11 +629,8 @@@ int mwifiex_set_tx_power(struct mwifiex
                }
        }
        buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
 -      if (!buf) {
 -              dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
 -                      __func__);
 +      if (!buf)
                return -ENOMEM;
 -      }
  
        txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
        txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
index 62ac607375314ea2359bee774266897baa28b320,1f7858588919dbde92f10b8c4f4fa2aeec3ee274..b9deef66cf4b8179893b918fbd0fb3365480a686
@@@ -84,8 -84,8 +84,8 @@@ static struct usb_device_id p54u_table[
        {USB_DEVICE(0x06b9, 0x0121)},   /* Thomson SpeedTouch 121g */
        {USB_DEVICE(0x0707, 0xee13)},   /* SMC 2862W-G version 2 */
        {USB_DEVICE(0x0803, 0x4310)},   /* Zoom 4410a */
-       {USB_DEVICE(0x083a, 0x4503)},   /* T-Com Sinus 154 data II */
        {USB_DEVICE(0x083a, 0x4521)},   /* Siemens Gigaset USB Adapter 54 version 2 */
+       {USB_DEVICE(0x083a, 0x4531)},   /* T-Com Sinus 154 data II */
        {USB_DEVICE(0x083a, 0xc501)},   /* Zoom Wireless-G 4410 */
        {USB_DEVICE(0x083a, 0xf503)},   /* Accton FD7050E ver 1010ec  */
        {USB_DEVICE(0x0846, 0x4240)},   /* Netgear WG111 (v2) */
@@@ -510,8 -510,11 +510,8 @@@ static int p54u_upload_firmware_3887(st
                return err;
  
        tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
 -      if (!buf) {
 -              dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
 -                                        "upload buffer!\n");
 +      if (!buf)
                return -ENOMEM;
 -      }
  
        left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
        strcpy(buf, p54u_firmware_upload_3887);
@@@ -634,8 -637,11 +634,8 @@@ static int p54u_upload_firmware_net2280
        const u8 *data;
  
        buf = kmalloc(512, GFP_KERNEL);
 -      if (!buf) {
 -              dev_err(&priv->udev->dev, "(p54usb) firmware buffer "
 -                                        "alloc failed!\n");
 +      if (!buf)
                return -ENOMEM;
 -      }
  
  #define P54U_WRITE(type, addr, data) \
        do {\
index 9bb3f22b3669ef2e135358dc3221a8596ec07c37,fe2f272689aad8163966f15850577460c9c083e0..525fd7521dffa0300e660f4600967be5780c8313
@@@ -1621,8 -1621,11 +1621,8 @@@ static void set_multicast_list(struct u
        } else if (mc_count) {
                int i = 0;
  
 -              mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
 +              mc_addrs = kmalloc_array(mc_count, ETH_ALEN, GFP_ATOMIC);
                if (!mc_addrs) {
 -                      netdev_warn(usbdev->net,
 -                                  "couldn't alloc %d bytes of memory\n",
 -                                  mc_count * ETH_ALEN);
                        netif_addr_unlock_bh(usbdev->net);
                        return;
                }
@@@ -2026,7 -2029,7 +2026,7 @@@ static bool rndis_bss_info_update(struc
        bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac,
                timestamp, capability, beacon_interval, ie, ie_len, signal,
                GFP_KERNEL);
-       cfg80211_put_bss(bss);
+       cfg80211_put_bss(priv->wdev.wiphy, bss);
  
        return (bss != NULL);
  }
@@@ -2715,7 -2718,7 +2715,7 @@@ static void rndis_wlan_craft_connected_
        bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
                timestamp, capability, beacon_period, ie_buf, ie_len,
                signal, GFP_KERNEL);
-       cfg80211_put_bss(bss);
+       cfg80211_put_bss(priv->wdev.wiphy, bss);
  }
  
  /*
index 910f8e2e556a2140326a2a0c9f9c863cbbc65186,c845b0ef7f4b4fda208fbd91ba2fe4ba5383939d..508f5b0f8a709d7fd2e416aaf20c18cfc5faa98e
@@@ -111,9 -111,9 +111,9 @@@ enum 
  
  struct wl1271_chip {
        u32 id;
 -      char fw_ver_str[ETHTOOL_BUSINFO_LEN];
 +      char fw_ver_str[ETHTOOL_FWVERS_LEN];
        unsigned int fw_ver[NUM_FW_VER];
 -      char phy_fw_ver_str[ETHTOOL_BUSINFO_LEN];
 +      char phy_fw_ver_str[ETHTOOL_FWVERS_LEN];
  };
  
  #define NUM_TX_QUEUES              4
@@@ -206,6 -206,11 +206,11 @@@ struct wl1271_if_operations 
        void (*set_block_size) (struct device *child, unsigned int blksz);
  };
  
+ struct wlcore_platdev_data {
+       struct wl12xx_platform_data *pdata;
+       struct wl1271_if_operations *if_ops;
+ };
  #define MAX_NUM_KEYS 14
  #define MAX_KEY_SIZE 32
  
index 1d31eab19d16b2d1ef5c2714162046da08c68500,a233f64ca22fa99c5c9288ba36ef5a3c7d8236e4..f1bce18ea828fe4f957705ec342508b16670f99a
@@@ -424,7 -424,7 +424,7 @@@ int prism2_scan(struct wiphy *wiphy, st
                        goto exit;
                }
  
-               cfg80211_put_bss(bss);
+               cfg80211_put_bss(wiphy, bss);
        }
  
        if (result)
@@@ -638,8 -638,8 +638,8 @@@ int prism2_leave_ibss(struct wiphy *wip
  }
  
  
 -int prism2_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type,
 -                      int mbm)
 +int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 +                      enum nl80211_tx_power_setting type, int mbm)
  {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
@@@ -665,8 -665,7 +665,8 @@@ exit
        return err;
  }
  
 -int prism2_get_tx_power(struct wiphy *wiphy, int *dbm)
 +int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 +                      int *dbm)
  {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
diff --combined include/net/cfg80211.h
index f9df20028bbdc62b617a91d84b207b185b466ab0,fa2612952c192dacd0b0ca3bcc95d4fd97317aef..d581c6de5d64a19db05d7763766a80bac4802acc
@@@ -19,6 -19,7 +19,7 @@@
  #include <linux/nl80211.h>
  #include <linux/if_ether.h>
  #include <linux/ieee80211.h>
+ #include <linux/net.h>
  #include <net/regulatory.h>
  
  /**
@@@ -99,6 -100,16 +100,16 @@@ enum ieee80211_band 
   * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel
   *    is not permitted.
   * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel.
+  * @IEEE80211_CHAN_NO_80MHZ: If the driver supports 80 MHz on the band,
+  *    this flag indicates that an 80 MHz channel cannot use this
+  *    channel as the control or any of the secondary channels.
+  *    This may be due to the driver or due to regulatory bandwidth
+  *    restrictions.
+  * @IEEE80211_CHAN_NO_160MHZ: If the driver supports 160 MHz on the band,
+  *    this flag indicates that an 160 MHz channel cannot use this
+  *    channel as the control or any of the secondary channels.
+  *    This may be due to the driver or due to regulatory bandwidth
+  *    restrictions.
   */
  enum ieee80211_channel_flags {
        IEEE80211_CHAN_DISABLED         = 1<<0,
        IEEE80211_CHAN_NO_HT40PLUS      = 1<<4,
        IEEE80211_CHAN_NO_HT40MINUS     = 1<<5,
        IEEE80211_CHAN_NO_OFDM          = 1<<6,
+       IEEE80211_CHAN_NO_80MHZ         = 1<<7,
+       IEEE80211_CHAN_NO_160MHZ        = 1<<8,
  };
  
  #define IEEE80211_CHAN_NO_HT40 \
        (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
  
+ #define IEEE80211_DFS_MIN_CAC_TIME_MS         60000
+ #define IEEE80211_DFS_MIN_NOP_TIME_MS         (30 * 60 * 1000)
  /**
   * struct ieee80211_channel - channel definition
   *
   *    to enable this, this is useful only on 5 GHz band.
   * @orig_mag: internal use
   * @orig_mpwr: internal use
+  * @dfs_state: current state of this channel. Only relevant if radar is required
+  *    on this channel.
+  * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
   */
  struct ieee80211_channel {
        enum ieee80211_band band;
        bool beacon_found;
        u32 orig_flags;
        int orig_mag, orig_mpwr;
+       enum nl80211_dfs_state dfs_state;
+       unsigned long dfs_state_entered;
  };
  
  /**
@@@ -535,7 -556,7 +556,7 @@@ struct mac_address 
   * struct cfg80211_acl_data - Access control list data
   *
   * @acl_policy: ACL policy to be applied on the station's
-       entry specified by mac_addr
+  *    entry specified by mac_addr
   * @n_acl_entries: Number of MAC address entries passed
   * @mac_addrs: List of MAC addresses of stations to be used for ACL
   */
@@@ -568,6 -589,7 +589,7 @@@ struct cfg80211_acl_data 
   * @p2p_opp_ps: P2P opportunistic PS
   * @acl: ACL configuration used by the drivers which has support for
   *    MAC address based access control
+  * @radar_required: set if radar detection is required
   */
  struct cfg80211_ap_settings {
        struct cfg80211_chan_def chandef;
        u8 p2p_ctwindow;
        bool p2p_opp_ps;
        const struct cfg80211_acl_data *acl;
+       bool radar_required;
  };
  
  /**
@@@ -603,12 -626,14 +626,14 @@@ enum plink_actions 
  /**
   * enum station_parameters_apply_mask - station parameter values to apply
   * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
+  * @STATION_PARAM_APPLY_CAPABILITY: apply new capability
   *
   * Not all station parameters have in-band "no change" signalling,
   * for those that don't these flags will are used.
   */
  enum station_parameters_apply_mask {
        STATION_PARAM_APPLY_UAPSD = BIT(0),
+       STATION_PARAM_APPLY_CAPABILITY = BIT(1),
  };
  
  /**
   *    see &enum station_parameters_apply_mask
   * @local_pm: local link-specific mesh power save mode (no change when set
   *    to unknown)
+  * @capability: station capability
+  * @ext_capab: extended capabilities of the station
+  * @ext_capab_len: number of extended capabilities
   */
  struct station_parameters {
        u8 *supported_rates;
        u8 uapsd_queues;
        u8 max_sp;
        enum nl80211_mesh_power_mode local_pm;
+       u16 capability;
+       u8 *ext_capab;
+       u8 ext_capab_len;
  };
  
  /**
   * @STATION_INFO_INACTIVE_TIME: @inactive_time filled
   * @STATION_INFO_RX_BYTES: @rx_bytes filled
   * @STATION_INFO_TX_BYTES: @tx_bytes filled
+  * @STATION_INFO_RX_BYTES64: @rx_bytes filled with 64-bit value
+  * @STATION_INFO_TX_BYTES64: @tx_bytes filled with 64-bit value
   * @STATION_INFO_LLID: @llid filled
   * @STATION_INFO_PLID: @plid filled
   * @STATION_INFO_PLINK_STATE: @plink_state filled
   * @STATION_INFO_SIGNAL: @signal filled
   * @STATION_INFO_TX_BITRATE: @txrate fields are filled
   *  (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
-  * @STATION_INFO_RX_PACKETS: @rx_packets filled
-  * @STATION_INFO_TX_PACKETS: @tx_packets filled
+  * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value
+  * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value
   * @STATION_INFO_TX_RETRIES: @tx_retries filled
   * @STATION_INFO_TX_FAILED: @tx_failed filled
   * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
@@@ -714,6 -747,8 +747,8 @@@ enum station_info_flags 
        STATION_INFO_LOCAL_PM           = 1<<21,
        STATION_INFO_PEER_PM            = 1<<22,
        STATION_INFO_NONPEER_PM         = 1<<23,
+       STATION_INFO_RX_BYTES64         = 1<<24,
+       STATION_INFO_TX_BYTES64         = 1<<25,
  };
  
  /**
@@@ -835,8 -870,8 +870,8 @@@ struct station_info 
        u32 filled;
        u32 connected_time;
        u32 inactive_time;
-       u32 rx_bytes;
-       u32 tx_bytes;
+       u64 rx_bytes;
+       u64 tx_bytes;
        u16 llid;
        u16 plid;
        u8 plink_state;
@@@ -1222,6 -1257,7 +1257,7 @@@ struct cfg80211_match_set 
   * @n_match_sets: number of match sets
   * @wiphy: the wiphy this was for
   * @dev: the interface
+  * @scan_start: start time of the scheduled scan
   * @channels: channels to scan
   * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
   */
@@@ -1261,11 -1297,13 +1297,13 @@@ enum cfg80211_signal_type 
  
  /**
   * struct cfg80211_bss_ie_data - BSS entry IE data
+  * @tsf: TSF contained in the frame that carried these IEs
   * @rcu_head: internal use, for freeing
   * @len: length of the IEs
   * @data: IE data
   */
  struct cfg80211_bss_ies {
+       u64 tsf;
        struct rcu_head rcu_head;
        int len;
        u8 data[];
   *
   * @channel: channel this BSS is on
   * @bssid: BSSID of the BSS
-  * @tsf: timestamp of last received update
   * @beacon_interval: the beacon interval as from the frame
   * @capability: the capability field in host byte order
-  * @ies: the information elements (Note that there
-  *    is no guarantee that these are well-formed!); this is a pointer to
-  *    either the beacon_ies or proberesp_ies depending on whether Probe
-  *    Response frame has been received
+  * @ies: the information elements (Note that there is no guarantee that these
+  *    are well-formed!); this is a pointer to either the beacon_ies or
+  *    proberesp_ies depending on whether Probe Response frame has been
+  *    received. It is always non-%NULL.
   * @beacon_ies: the information elements from the last Beacon frame
+  *    (implementation note: if @hidden_beacon_bss is set this struct doesn't
+  *    own the beacon_ies, but they're just pointers to the ones from the
+  *    @hidden_beacon_bss struct)
   * @proberesp_ies: the information elements from the last Probe Response frame
+  * @hidden_beacon_bss: in case this BSS struct represents a probe response from
+  *    a BSS that hides the SSID in its beacon, this points to the BSS struct
+  *    that holds the beacon data. @beacon_ies is still valid, of course, and
+  *    points to the same data as hidden_beacon_bss->beacon_ies in that case.
   * @signal: signal strength value (type depends on the wiphy's signal_type)
-  * @free_priv: function pointer to free private data
   * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
   */
  struct cfg80211_bss {
-       u64 tsf;
        struct ieee80211_channel *channel;
  
        const struct cfg80211_bss_ies __rcu *ies;
        const struct cfg80211_bss_ies __rcu *beacon_ies;
        const struct cfg80211_bss_ies __rcu *proberesp_ies;
  
-       void (*free_priv)(struct cfg80211_bss *bss);
+       struct cfg80211_bss *hidden_beacon_bss;
  
        s32 signal;
  
@@@ -1403,6 -1444,8 +1444,8 @@@ struct cfg80211_assoc_request 
   * @ie: Extra IEs to add to Deauthentication frame or %NULL
   * @ie_len: Length of ie buffer in octets
   * @reason_code: The reason code for the deauthentication
+  * @local_state_change: if set, change local state only and
+  *    do not set a deauth frame
   */
  struct cfg80211_deauth_request {
        const u8 *bssid;
@@@ -1564,6 -1607,7 +1607,7 @@@ struct cfg80211_pmksa 
   *    one bit per byte, in same format as nl80211
   * @pattern: bytes to match where bitmask is 1
   * @pattern_len: length of pattern (in bytes)
+  * @pkt_offset: packet offset (in bytes)
   *
   * Internal note: @mask and @pattern are allocated in one chunk of
   * memory, free @mask only!
  struct cfg80211_wowlan_trig_pkt_pattern {
        u8 *mask, *pattern;
        int pattern_len;
+       int pkt_offset;
+ };
+ /**
+  * struct cfg80211_wowlan_tcp - TCP connection parameters
+  *
+  * @sock: (internal) socket for source port allocation
+  * @src: source IP address
+  * @dst: destination IP address
+  * @dst_mac: destination MAC address
+  * @src_port: source port
+  * @dst_port: destination port
+  * @payload_len: data payload length
+  * @payload: data payload buffer
+  * @payload_seq: payload sequence stamping configuration
+  * @data_interval: interval at which to send data packets
+  * @wake_len: wakeup payload match length
+  * @wake_data: wakeup payload match data
+  * @wake_mask: wakeup payload match mask
+  * @tokens_size: length of the tokens buffer
+  * @payload_tok: payload token usage configuration
+  */
+ struct cfg80211_wowlan_tcp {
+       struct socket *sock;
+       __be32 src, dst;
+       u16 src_port, dst_port;
+       u8 dst_mac[ETH_ALEN];
+       int payload_len;
+       const u8 *payload;
+       struct nl80211_wowlan_tcp_data_seq payload_seq;
+       u32 data_interval;
+       u32 wake_len;
+       const u8 *wake_data, *wake_mask;
+       u32 tokens_size;
+       /* must be last, variable member */
+       struct nl80211_wowlan_tcp_data_token payload_tok;
  };
  
  /**
   * @eap_identity_req: wake up on EAP identity request packet
   * @four_way_handshake: wake up on 4-way handshake
   * @rfkill_release: wake up when rfkill is released
+  * @tcp: TCP connection establishment/wakeup parameters, see nl80211.h.
+  *    NULL if not configured.
   */
  struct cfg80211_wowlan {
        bool any, disconnect, magic_pkt, gtk_rekey_failure,
             eap_identity_req, four_way_handshake,
             rfkill_release;
        struct cfg80211_wowlan_trig_pkt_pattern *patterns;
+       struct cfg80211_wowlan_tcp *tcp;
        int n_patterns;
  };
  
+ /**
+  * struct cfg80211_wowlan_wakeup - wakeup report
+  * @disconnect: woke up by getting disconnected
+  * @magic_pkt: woke up by receiving magic packet
+  * @gtk_rekey_failure: woke up by GTK rekey failure
+  * @eap_identity_req: woke up by EAP identity request packet
+  * @four_way_handshake: woke up by 4-way handshake
+  * @rfkill_release: woke up by rfkill being released
+  * @pattern_idx: pattern that caused wakeup, -1 if not due to pattern
+  * @packet_present_len: copied wakeup packet data
+  * @packet_len: original wakeup packet length
+  * @packet: The packet causing the wakeup, if any.
+  * @packet_80211:  For pattern match, magic packet and other data
+  *    frame triggers an 802.3 frame should be reported, for
+  *    disconnect due to deauth 802.11 frame. This indicates which
+  *    it is.
+  * @tcp_match: TCP wakeup packet received
+  * @tcp_connlost: TCP connection lost or failed to establish
+  * @tcp_nomoretokens: TCP data ran out of tokens
+  */
+ struct cfg80211_wowlan_wakeup {
+       bool disconnect, magic_pkt, gtk_rekey_failure,
+            eap_identity_req, four_way_handshake,
+            rfkill_release, packet_80211,
+            tcp_match, tcp_connlost, tcp_nomoretokens;
+       s32 pattern_idx;
+       u32 packet_present_len, packet_len;
+       const void *packet;
+ };
  /**
   * struct cfg80211_gtk_rekey_data - rekey data
   * @kek: key encryption key
@@@ -1826,6 -1939,8 +1939,8 @@@ struct cfg80211_gtk_rekey_data 
   *    this new list replaces the existing one. Driver has to clear its ACL
   *    when number of MAC addresses entries is passed as 0. Drivers which
   *    advertise the support for MAC based ACL have to implement this callback.
+  *
+  * @start_radar_detection: Start radar detection in the driver.
   */
  struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
  
        int     (*set_mac_acl)(struct wiphy *wiphy, struct net_device *dev,
                               const struct cfg80211_acl_data *params);
+       int     (*start_radar_detection)(struct wiphy *wiphy,
+                                        struct net_device *dev,
+                                        struct cfg80211_chan_def *chandef);
  };
  
  /*
@@@ -2245,6 -2364,14 +2364,14 @@@ enum wiphy_wowlan_support_flags 
        WIPHY_WOWLAN_RFKILL_RELEASE     = BIT(7),
  };
  
+ struct wiphy_wowlan_tcp_support {
+       const struct nl80211_wowlan_tcp_data_token_feature *tok;
+       u32 data_payload_max;
+       u32 data_interval_max;
+       u32 wake_payload_max;
+       bool seq;
+ };
  /**
   * struct wiphy_wowlan_support - WoWLAN support data
   * @flags: see &enum wiphy_wowlan_support_flags
   *    (see nl80211.h for the pattern definition)
   * @pattern_max_len: maximum length of each pattern
   * @pattern_min_len: minimum length of each pattern
+  * @max_pkt_offset: maximum Rx packet offset
+  * @tcp: TCP wakeup support information
   */
  struct wiphy_wowlan_support {
        u32 flags;
        int n_patterns;
        int pattern_max_len;
        int pattern_min_len;
+       int max_pkt_offset;
+       const struct wiphy_wowlan_tcp_support *tcp;
  };
  
  /**
   *
   * @max_acl_mac_addrs: Maximum number of MAC addresses that the device
   *    supports for ACL.
+  *
+  * @extended_capabilities: extended capabilities supported by the driver,
+  *    additional capabilities might be supported by userspace; these are
+  *    the 802.11 extended capabilities ("Extended Capabilities element")
+  *    and are in the same format as in the information element. See
+  *    802.11-2012 8.4.2.29 for the defined fields.
+  * @extended_capabilities_mask: mask of the valid values
+  * @extended_capabilities_len: length of the extended capabilities
   */
  struct wiphy {
        /* assign these fields before you register the wiphy */
        u32 rts_threshold;
        u8 coverage_class;
  
 -      char fw_version[ETHTOOL_BUSINFO_LEN];
 +      char fw_version[ETHTOOL_FWVERS_LEN];
        u32 hw_version;
  
  #ifdef CONFIG_PM
         */
        u32 probe_resp_offload;
  
+       const u8 *extended_capabilities, *extended_capabilities_mask;
+       u8 extended_capabilities_len;
        /* If multiple wiphys are registered and you're handed e.g.
         * a regular netdev with assigned ieee80211_ptr, you won't
         * know whether it points to a wiphy your driver has registered
@@@ -2602,7 -2744,6 +2744,6 @@@ struct cfg80211_cached_keys
   *    the user-set AP, monitor and WDS channel
   * @preset_chan: (private) Used by the internal configuration code to
   *    track the channel to be used for AP later
-  * @preset_chantype: (private) the corresponding channel type
   * @bssid: (private) Used by the internal configuration code
   * @ssid: (private) Used by the internal configuration code
   * @ssid_len: (private) Used by the internal configuration code
   *    beacons, 0 when not valid
   * @address: The address for this device, valid only if @netdev is %NULL
   * @p2p_started: true if this is a P2P Device that has been started
+  * @cac_started: true if DFS channel availability check has been started
+  * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
   */
  struct wireless_dev {
        struct wiphy *wiphy;
  
        u32 ap_unexpected_nlportid;
  
+       bool cac_started;
+       unsigned long cac_start_time;
  #ifdef CONFIG_CFG80211_WEXT
        /* wext data */
        struct {
@@@ -3137,25 -3283,23 +3283,23 @@@ cfg80211_get_ibss(struct wiphy *wiphy
                                WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
  }
  
- struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
-                                      struct ieee80211_channel *channel,
-                                      const u8 *meshid, size_t meshidlen,
-                                      const u8 *meshcfg);
  /**
   * cfg80211_ref_bss - reference BSS struct
+  * @wiphy: the wiphy this BSS struct belongs to
   * @bss: the BSS struct to reference
   *
   * Increments the refcount of the given BSS struct.
   */
- void cfg80211_ref_bss(struct cfg80211_bss *bss);
+ void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
  
  /**
   * cfg80211_put_bss - unref BSS struct
+  * @wiphy: the wiphy this BSS struct belongs to
   * @bss: the BSS struct
   *
   * Decrements the refcount of the given BSS struct.
   */
- void cfg80211_put_bss(struct cfg80211_bss *bss);
+ void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
  
  /**
   * cfg80211_unlink_bss - unlink BSS from internal data structures
@@@ -3662,6 -3806,31 +3806,31 @@@ void cfg80211_cqm_rssi_notify(struct ne
                              enum nl80211_cqm_rssi_threshold_event rssi_event,
                              gfp_t gfp);
  
+ /**
+  * cfg80211_radar_event - radar detection event
+  * @wiphy: the wiphy
+  * @chandef: chandef for the current channel
+  * @gfp: context flags
+  *
+  * This function is called when a radar is detected on the current chanenl.
+  */
+ void cfg80211_radar_event(struct wiphy *wiphy,
+                         struct cfg80211_chan_def *chandef, gfp_t gfp);
+ /**
+  * cfg80211_cac_event - Channel availability check (CAC) event
+  * @netdev: network device
+  * @event: type of event
+  * @gfp: context flags
+  *
+  * This function is called when a Channel availability check (CAC) is finished
+  * or aborted. This must be called to notify the completion of a CAC process,
+  * also by full-MAC drivers.
+  */
+ void cfg80211_cac_event(struct net_device *netdev,
+                       enum nl80211_radar_event event, gfp_t gfp);
  /**
   * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer
   * @dev: network device
@@@ -3852,6 -4021,21 +4021,21 @@@ int cfg80211_get_p2p_attr(const u8 *ies
                          enum ieee80211_p2p_attr_id attr,
                          u8 *buf, unsigned int bufsize);
  
+ /**
+  * cfg80211_report_wowlan_wakeup - report wakeup from WoWLAN
+  * @wdev: the wireless device reporting the wakeup
+  * @wakeup: the wakeup report
+  * @gfp: allocation flags
+  *
+  * This function reports that the given device woke up. If it
+  * caused the wakeup, report the reason(s), otherwise you may
+  * pass %NULL as the @wakeup parameter to advertise that something
+  * else caused the wakeup.
+  */
+ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
+                                  struct cfg80211_wowlan_wakeup *wakeup,
+                                  gfp_t gfp);
  /* Logging, debugging and troubleshooting/diagnostic helpers. */
  
  /* wiphy_printk helpers, similar to dev_printk */
diff --combined net/wireless/core.c
index 40dbe37cfbf6389c7f3178f474ddb58174b676db,33b75b9b8efa5c635d5927c571f56a157bc36782..5ffff039b0174eefb8f3967dc6f5307ea7cb2f8c
@@@ -324,6 -324,8 +324,8 @@@ struct wiphy *wiphy_new(const struct cf
        INIT_LIST_HEAD(&rdev->bss_list);
        INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
        INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
+       INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk,
+                         cfg80211_dfs_channels_update_work);
  #ifdef CONFIG_CFG80211_WEXT
        rdev->wiphy.wext = &cfg80211_wext_handler;
  #endif
        rdev->wiphy.rts_threshold = (u32) -1;
        rdev->wiphy.coverage_class = 0;
  
-       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH;
+       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH |
+                              NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
  
        return &rdev->wiphy;
  }
@@@ -695,6 -698,7 +698,7 @@@ void wiphy_unregister(struct wiphy *wip
        flush_work(&rdev->scan_done_wk);
        cancel_work_sync(&rdev->conn_work);
        flush_work(&rdev->event_work);
+       cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
  
        if (rdev->wowlan && rdev->ops->set_wakeup)
                rdev_set_wakeup(rdev, false);
@@@ -715,7 -719,7 +719,7 @@@ void cfg80211_dev_free(struct cfg80211_
                kfree(reg);
        }
        list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
-               cfg80211_put_bss(&scan->pub);
+               cfg80211_put_bss(&rdev->wiphy, &scan->pub);
        kfree(rdev);
  }
  
@@@ -871,7 -875,8 +875,7 @@@ static int cfg80211_netdev_notifier_cal
                /* allow mac80211 to determine the timeout */
                wdev->ps_timeout = -1;
  
 -              if (!dev->ethtool_ops)
 -                      dev->ethtool_ops = &cfg80211_ethtool_ops;
 +              netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops);
  
                if ((wdev->iftype == NL80211_IFTYPE_STATION ||
                     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
diff --combined net/wireless/reg.c
index de02d633c212eb6ea516a7d87e05978a2a1b3ba9,93ab840957a045bfb4333bad63aa65977dedf8d2..98532c00242dd4a1a134e12f388a340434b38c04
@@@ -866,6 -866,10 +866,10 @@@ static void handle_channel(struct wiph
  
        if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
                bw_flags = IEEE80211_CHAN_NO_HT40;
+       if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(80))
+               bw_flags |= IEEE80211_CHAN_NO_80MHZ;
+       if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(160))
+               bw_flags |= IEEE80211_CHAN_NO_160MHZ;
  
        if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
            request_wiphy && request_wiphy == wiphy &&
                return;
        }
  
+       chan->dfs_state = NL80211_DFS_USABLE;
+       chan->dfs_state_entered = jiffies;
        chan->beacon_found = false;
        chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
        chan->max_antenna_gain =
@@@ -1261,6 -1268,10 +1268,10 @@@ static void handle_channel_custom(struc
  
        if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
                bw_flags = IEEE80211_CHAN_NO_HT40;
+       if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(80))
+               bw_flags |= IEEE80211_CHAN_NO_80MHZ;
+       if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(160))
+               bw_flags |= IEEE80211_CHAN_NO_160MHZ;
  
        chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
        chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
@@@ -2189,10 -2200,15 +2200,15 @@@ static int __set_regdom(const struct ie
                 * However if a driver requested this specific regulatory
                 * domain we keep it for its private use
                 */
-               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER)
+               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
+                       const struct ieee80211_regdomain *tmp;
+                       tmp = get_wiphy_regdom(request_wiphy);
                        rcu_assign_pointer(request_wiphy->regd, rd);
-               else
+                       rcu_free_regdom(tmp);
+               } else {
                        kfree(rd);
+               }
  
                rd = NULL;
  
@@@ -2249,6 -2265,7 +2265,6 @@@ int set_regdom(const struct ieee80211_r
        return r;
  }
  
 -#ifdef CONFIG_HOTPLUG
  int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
  {
        struct regulatory_request *lr;
                                      alpha2[0], alpha2[1]);
        return 0;
  }
 -#else
 -int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 -{
 -      return -ENODEV;
 -}
 -#endif /* CONFIG_HOTPLUG */
  
  void wiphy_regulatory_register(struct wiphy *wiphy)
  {
diff --combined net/wireless/sysfs.c
index 1f6f01e2dc4cb9f0a5528f459b6e6c49dba47cb1,73bf39f113146ca160f0f6b67d539001f4c3067b..238ee49b3868b8d675e3328f279608eee970fd7f
@@@ -77,11 -77,13 +77,11 @@@ static void wiphy_dev_release(struct de
        cfg80211_dev_free(rdev);
  }
  
 -#ifdef CONFIG_HOTPLUG
  static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
  {
        /* TODO, we probably need stuff here */
        return 0;
  }
 -#endif
  
  static int wiphy_suspend(struct device *dev, pm_message_t state)
  {
@@@ -106,9 -108,7 +106,7 @@@ static int wiphy_resume(struct device *
        int ret = 0;
  
        /* Age scan results with time spent in suspend */
-       spin_lock_bh(&rdev->bss_lock);
        cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at);
-       spin_unlock_bh(&rdev->bss_lock);
  
        if (rdev->ops->resume) {
                rtnl_lock();
@@@ -132,7 -132,9 +130,7 @@@ struct class ieee80211_class = 
        .owner = THIS_MODULE,
        .dev_release = wiphy_dev_release,
        .dev_attrs = ieee80211_dev_attrs,
 -#ifdef CONFIG_HOTPLUG
        .dev_uevent = wiphy_uevent,
 -#endif
        .suspend = wiphy_suspend,
        .resume = wiphy_resume,
        .ns_type = &net_ns_type_operations,
This page took 0.180103 seconds and 4 git commands to generate.