These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / wireless / mwifiex / cfg80211.c
index bf9020f..4073116 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "cfg80211.h"
 #include "main.h"
+#include "11n.h"
 
 static char *reg_alpha2;
 module_param(reg_alpha2, charp, 0);
@@ -34,12 +35,38 @@ static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
        },
 };
 
-static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
+static const struct ieee80211_iface_combination
+mwifiex_iface_comb_ap_sta = {
        .limits = mwifiex_ap_sta_limits,
        .num_different_channels = 1,
        .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
        .max_interfaces = MWIFIEX_MAX_BSS_NUM,
        .beacon_int_infra_match = true,
+       .radar_detect_widths =  BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+                               BIT(NL80211_CHAN_WIDTH_20) |
+                               BIT(NL80211_CHAN_WIDTH_40),
+};
+
+static const struct ieee80211_iface_combination
+mwifiex_iface_comb_ap_sta_vht = {
+       .limits = mwifiex_ap_sta_limits,
+       .num_different_channels = 1,
+       .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
+       .max_interfaces = MWIFIEX_MAX_BSS_NUM,
+       .beacon_int_infra_match = true,
+       .radar_detect_widths =  BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+                               BIT(NL80211_CHAN_WIDTH_20) |
+                               BIT(NL80211_CHAN_WIDTH_40) |
+                               BIT(NL80211_CHAN_WIDTH_80),
+};
+
+static const struct
+ieee80211_iface_combination mwifiex_iface_comb_ap_sta_drcs = {
+       .limits = mwifiex_ap_sta_limits,
+       .num_different_channels = 2,
+       .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
+       .max_interfaces = MWIFIEX_MAX_BSS_NUM,
+       .beacon_int_infra_match = true,
 };
 
 /*
@@ -67,6 +94,22 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
        }
 }
 
+/* This function maps IEEE HT secondary channel type to NL80211 channel type
+ */
+u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset)
+{
+       switch (second_chan_offset) {
+       case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+               return NL80211_CHAN_HT20;
+       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+               return NL80211_CHAN_HT40PLUS;
+       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+               return NL80211_CHAN_HT40MINUS;
+       default:
+               return NL80211_CHAN_HT20;
+       }
+}
+
 /*
  * This function checks whether WEP is set.
  */
@@ -104,11 +147,11 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
        const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
 
        if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
-               wiphy_err(wiphy, "deleting the crypto keys\n");
+               mwifiex_dbg(priv->adapter, ERROR, "deleting the crypto keys\n");
                return -EFAULT;
        }
 
-       wiphy_dbg(wiphy, "info: crypto keys deleted\n");
+       mwifiex_dbg(priv->adapter, INFO, "info: crypto keys deleted\n");
        return 0;
 }
 
@@ -163,7 +206,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
 
        if (!buf || !len) {
-               wiphy_err(wiphy, "invalid buffer and length\n");
+               mwifiex_dbg(priv->adapter, ERROR, "invalid buffer and length\n");
                return -EFAULT;
        }
 
@@ -172,8 +215,8 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
            ieee80211_is_probe_resp(mgmt->frame_control)) {
                /* Since we support offload probe resp, we need to skip probe
                 * resp in AP or GO mode */
-               wiphy_dbg(wiphy,
-                         "info: skip to send probe resp in AP or GO mode\n");
+               mwifiex_dbg(priv->adapter, INFO,
+                           "info: skip to send probe resp in AP or GO mode\n");
                return 0;
        }
 
@@ -183,7 +226,8 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                            pkt_len + sizeof(pkt_len));
 
        if (!skb) {
-               wiphy_err(wiphy, "allocate skb failed for management frame\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "allocate skb failed for management frame\n");
                return -ENOMEM;
        }
 
@@ -206,7 +250,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 
        mwifiex_queue_tx_pkt(priv, skb);
 
-       wiphy_dbg(wiphy, "info: management frame transmitted\n");
+       mwifiex_dbg(priv->adapter, INFO, "info: management frame transmitted\n");
        return 0;
 }
 
@@ -231,7 +275,7 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
                mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
                                 HostCmd_ACT_GEN_SET, 0,
                                 &priv->mgmt_frame_mask, false);
-               wiphy_dbg(wiphy, "info: mgmt frame registered\n");
+               mwifiex_dbg(priv->adapter, INFO, "info: mgmt frame registered\n");
        }
 }
 
@@ -248,13 +292,14 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
        int ret;
 
        if (!chan || !cookie) {
-               wiphy_err(wiphy, "Invalid parameter for ROC\n");
+               mwifiex_dbg(priv->adapter, ERROR, "Invalid parameter for ROC\n");
                return -EINVAL;
        }
 
        if (priv->roc_cfg.cookie) {
-               wiphy_dbg(wiphy, "info: ongoing ROC, cookie = 0x%llx\n",
-                         priv->roc_cfg.cookie);
+               mwifiex_dbg(priv->adapter, INFO,
+                           "info: ongoing ROC, cookie = 0x%llx\n",
+                           priv->roc_cfg.cookie);
                return -EBUSY;
        }
 
@@ -269,7 +314,8 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
                cfg80211_ready_on_channel(wdev, *cookie, chan,
                                          duration, GFP_ATOMIC);
 
-               wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
+               mwifiex_dbg(priv->adapter, INFO,
+                           "info: ROC, cookie = 0x%llx\n", *cookie);
        }
 
        return ret;
@@ -298,7 +344,8 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
 
                memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
 
-               wiphy_dbg(wiphy, "info: cancel ROC, cookie = 0x%llx\n", cookie);
+               mwifiex_dbg(priv->adapter, INFO,
+                           "info: cancel ROC, cookie = 0x%llx\n", cookie);
        }
 
        return ret;
@@ -344,8 +391,8 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
        u32 ps_mode;
 
        if (timeout)
-               wiphy_dbg(wiphy,
-                         "info: ignore timeout value for IEEE Power Save\n");
+               mwifiex_dbg(priv->adapter, INFO,
+                           "info: ignore timeout value for IEEE Power Save\n");
 
        ps_mode = enabled;
 
@@ -370,7 +417,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
                priv->wep_key_curr_index = key_index;
        } else if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index,
                                      NULL, 0)) {
-               wiphy_err(wiphy, "set default Tx key index\n");
+               mwifiex_dbg(priv->adapter, ERROR, "set default Tx key index\n");
                return -EFAULT;
        }
 
@@ -407,7 +454,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
 
        if (mwifiex_set_encode(priv, params, params->key, params->key_len,
                               key_index, peer_mac, 0)) {
-               wiphy_err(wiphy, "crypto keys added\n");
+               mwifiex_dbg(priv->adapter, ERROR, "crypto keys added\n");
                return -EFAULT;
        }
 
@@ -421,7 +468,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
  *      - Country codes
  *      - Sub bands (first channel, number of channels, maximum Tx power)
  */
-static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
+int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
 {
        u8 no_of_triplet = 0;
        struct ieee80211_country_ie_triplet *t;
@@ -442,7 +489,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
 
        band = mwifiex_band_to_radio_type(adapter->config_bands);
        if (!wiphy->bands[band]) {
-               wiphy_err(wiphy, "11D: setting domain info in FW\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "11D: setting domain info in FW\n");
                return -1;
        }
 
@@ -493,7 +541,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
 
        if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
                             HostCmd_ACT_GEN_SET, 0, NULL, false)) {
-               wiphy_err(wiphy, "11D: setting domain info in FW\n");
+               mwifiex_dbg(adapter, INFO,
+                           "11D: setting domain info in FW\n");
                return -1;
        }
 
@@ -516,9 +565,9 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy,
        struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
        struct mwifiex_private *priv = mwifiex_get_priv(adapter,
                                                        MWIFIEX_BSS_ROLE_ANY);
-
-       wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n",
-                 request->alpha2[0], request->alpha2[1]);
+       mwifiex_dbg(adapter, INFO,
+                   "info: cfg80211 regulatory domain callback for %c%c\n",
+                   request->alpha2[0], request->alpha2[1]);
 
        switch (request->initiator) {
        case NL80211_REGDOM_SET_BY_DRIVER:
@@ -527,8 +576,9 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy,
        case NL80211_REGDOM_SET_BY_COUNTRY_IE:
                break;
        default:
-               wiphy_err(wiphy, "unknown regdom initiator: %d\n",
-                         request->initiator);
+               mwifiex_dbg(adapter, ERROR,
+                           "unknown regdom initiator: %d\n",
+                           request->initiator);
                return;
        }
 
@@ -597,8 +647,8 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
        switch (priv->bss_role) {
        case MWIFIEX_BSS_ROLE_UAP:
                if (priv->bss_started) {
-                       dev_err(adapter->dev,
-                               "cannot change wiphy params when bss started");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "cannot change wiphy params when bss started");
                        return -EINVAL;
                }
 
@@ -622,15 +672,16 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 
                kfree(bss_cfg);
                if (ret) {
-                       wiphy_err(wiphy, "Failed to set wiphy phy params\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "Failed to set wiphy phy params\n");
                        return ret;
                }
                break;
 
                case MWIFIEX_BSS_ROLE_STA:
                if (priv->media_connected) {
-                       dev_err(adapter->dev,
-                               "cannot change wiphy params when connected");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "cannot change wiphy params when connected");
                        return -EINVAL;
                }
                if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
@@ -724,8 +775,8 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
        if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
                             HostCmd_ACT_GEN_SET, 0,
                             &priv->mgmt_frame_mask, false)) {
-               dev_warn(priv->adapter->dev,
-                        "could not unregister mgmt frame rx\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "could not unregister mgmt frame rx\n");
                return -1;
        }
 
@@ -780,18 +831,21 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
                priv->bss_type = MWIFIEX_BSS_TYPE_STA;
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
-       case NL80211_IFTYPE_P2P_GO:
                priv->bss_role =  MWIFIEX_BSS_ROLE_STA;
                priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
                break;
+       case NL80211_IFTYPE_P2P_GO:
+               priv->bss_role =  MWIFIEX_BSS_ROLE_UAP;
+               priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
+               break;
        case NL80211_IFTYPE_AP:
                priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
                priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
                break;
        default:
-               dev_err(priv->adapter->dev,
-                       "%s: changing to %d not supported\n",
-                       dev->name, type);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: changing to %d not supported\n",
+                           dev->name, type);
                return -EOPNOTSUPP;
        }
 
@@ -824,12 +878,13 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
 
        if (adapter->curr_iface_comb.p2p_intf ==
            adapter->iface_limit.p2p_intf) {
-               dev_err(adapter->dev,
-                       "cannot create multiple P2P ifaces\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "cannot create multiple P2P ifaces\n");
                return -1;
        }
 
-       dev_dbg(priv->adapter->dev, "%s: changing role to p2p\n", dev->name);
+       mwifiex_dbg(adapter, INFO,
+                   "%s: changing role to p2p\n", dev->name);
 
        if (mwifiex_deinit_priv_params(priv))
                return -1;
@@ -846,9 +901,9 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
                        return -EFAULT;
                break;
        default:
-               dev_err(priv->adapter->dev,
-                       "%s: changing to %d not supported\n",
-                       dev->name, type);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: changing to %d not supported\n",
+                           dev->name, type);
                return -EOPNOTSUPP;
        }
 
@@ -897,17 +952,17 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
             curr_iftype != NL80211_IFTYPE_P2P_GO) &&
            (adapter->curr_iface_comb.sta_intf ==
             adapter->iface_limit.sta_intf)) {
-               dev_err(adapter->dev,
-                       "cannot create multiple station/adhoc ifaces\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "cannot create multiple station/adhoc ifaces\n");
                return -1;
        }
 
        if (type == NL80211_IFTYPE_STATION)
-               dev_notice(adapter->dev,
-                          "%s: changing role to station\n", dev->name);
+               mwifiex_dbg(adapter, INFO,
+                           "%s: changing role to station\n", dev->name);
        else
-               dev_notice(adapter->dev,
-                          "%s: changing role to adhoc\n", dev->name);
+               mwifiex_dbg(adapter, INFO,
+                           "%s: changing role to adhoc\n", dev->name);
 
        if (mwifiex_deinit_priv_params(priv))
                return -1;
@@ -954,12 +1009,13 @@ mwifiex_change_vif_to_ap(struct net_device *dev,
 
        if (adapter->curr_iface_comb.uap_intf ==
            adapter->iface_limit.uap_intf) {
-               dev_err(adapter->dev,
-                       "cannot create multiple AP ifaces\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "cannot create multiple AP ifaces\n");
                return -1;
        }
 
-       dev_notice(adapter->dev, "%s: changing role to AP\n", dev->name);
+       mwifiex_dbg(adapter, INFO,
+                   "%s: changing role to AP\n", dev->name);
 
        if (mwifiex_deinit_priv_params(priv))
                return -1;
@@ -1020,12 +1076,14 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
                        return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
                                                        flags, params);
                case NL80211_IFTYPE_UNSPECIFIED:
-                       wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
+                       mwifiex_dbg(priv->adapter, INFO,
+                                   "%s: kept type as IBSS\n", dev->name);
                case NL80211_IFTYPE_ADHOC:      /* This shouldn't happen */
                        return 0;
                default:
-                       wiphy_err(wiphy, "%s: changing to %d not supported\n",
-                                 dev->name, type);
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "%s: changing to %d not supported\n",
+                                   dev->name, type);
                        return -EOPNOTSUPP;
                }
                break;
@@ -1048,12 +1106,14 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
                        return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
                                                        flags, params);
                case NL80211_IFTYPE_UNSPECIFIED:
-                       wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
+                       mwifiex_dbg(priv->adapter, INFO,
+                                   "%s: kept type as STA\n", dev->name);
                case NL80211_IFTYPE_STATION:    /* This shouldn't happen */
                        return 0;
                default:
-                       wiphy_err(wiphy, "%s: changing to %d not supported\n",
-                                 dev->name, type);
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "%s: changing to %d not supported\n",
+                                   dev->name, type);
                        return -EOPNOTSUPP;
                }
                break;
@@ -1070,12 +1130,14 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
                        return mwifiex_change_vif_to_p2p(dev, curr_iftype,
                                                         type, flags, params);
                case NL80211_IFTYPE_UNSPECIFIED:
-                       wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
+                       mwifiex_dbg(priv->adapter, INFO,
+                                   "%s: kept type as AP\n", dev->name);
                case NL80211_IFTYPE_AP:         /* This shouldn't happen */
                        return 0;
                default:
-                       wiphy_err(wiphy, "%s: changing to %d not supported\n",
-                                 dev->name, type);
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "%s: changing to %d not supported\n",
+                                   dev->name, type);
                        return -EOPNOTSUPP;
                }
                break;
@@ -1083,8 +1145,10 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
        case NL80211_IFTYPE_P2P_GO:
                switch (type) {
                case NL80211_IFTYPE_STATION:
-                       if (mwifiex_cfg80211_init_p2p_client(priv))
+                       if (mwifiex_cfg80211_deinit_p2p(priv))
                                return -EFAULT;
+                       priv->adapter->curr_iface_comb.p2p_intf--;
+                       priv->adapter->curr_iface_comb.sta_intf++;
                        dev->ieee80211_ptr->iftype = type;
                        break;
                case NL80211_IFTYPE_ADHOC:
@@ -1100,19 +1164,22 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
                        return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
                                                        flags, params);
                case NL80211_IFTYPE_UNSPECIFIED:
-                       wiphy_warn(wiphy, "%s: kept type as P2P\n", dev->name);
+                       mwifiex_dbg(priv->adapter, INFO,
+                                   "%s: kept type as P2P\n", dev->name);
                case NL80211_IFTYPE_P2P_CLIENT:
                case NL80211_IFTYPE_P2P_GO:
                        return 0;
                default:
-                       wiphy_err(wiphy, "%s: changing to %d not supported\n",
-                                 dev->name, type);
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "%s: changing to %d not supported\n",
+                                   dev->name, type);
                        return -EOPNOTSUPP;
                }
                break;
        default:
-               wiphy_err(wiphy, "%s: unknown iftype: %d\n",
-                         dev->name, dev->ieee80211_ptr->iftype);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "%s: unknown iftype: %d\n",
+                           dev->name, dev->ieee80211_ptr->iftype);
                return -EOPNOTSUPP;
        }
 
@@ -1194,6 +1261,7 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
  */
 static int
 mwifiex_dump_station_info(struct mwifiex_private *priv,
+                         struct mwifiex_sta_node *node,
                          struct station_info *sinfo)
 {
        u32 rate;
@@ -1203,15 +1271,41 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
                        BIT(NL80211_STA_INFO_TX_BITRATE) |
                        BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG);
 
+       if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
+               if (!node)
+                       return -ENOENT;
+
+               sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME) |
+                               BIT(NL80211_STA_INFO_TX_FAILED);
+               sinfo->inactive_time =
+                       jiffies_to_msecs(jiffies - node->stats.last_rx);
+
+               sinfo->signal = node->stats.rssi;
+               sinfo->signal_avg = node->stats.rssi;
+               sinfo->rx_bytes = node->stats.rx_bytes;
+               sinfo->tx_bytes = node->stats.tx_bytes;
+               sinfo->rx_packets = node->stats.rx_packets;
+               sinfo->tx_packets = node->stats.tx_packets;
+               sinfo->tx_failed = node->stats.tx_failed;
+
+               mwifiex_parse_htinfo(priv, node->stats.last_tx_htinfo,
+                                    &sinfo->txrate);
+               sinfo->txrate.legacy = node->stats.last_tx_rate * 5;
+
+               return 0;
+       }
+
        /* Get signal information from the firmware */
        if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
                             HostCmd_ACT_GEN_GET, 0, NULL, true)) {
-               dev_err(priv->adapter->dev, "failed to get signal information\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "failed to get signal information\n");
                return -EFAULT;
        }
 
        if (mwifiex_drv_get_data_rate(priv, &rate)) {
-               dev_err(priv->adapter->dev, "getting data rate\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "getting data rate error\n");
                return -EFAULT;
        }
 
@@ -1267,7 +1361,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
        if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
                return -ENOENT;
 
-       return mwifiex_dump_station_info(priv, sinfo);
+       return mwifiex_dump_station_info(priv, NULL, sinfo);
 }
 
 /*
@@ -1278,13 +1372,29 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
                              int idx, u8 *mac, struct station_info *sinfo)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+       static struct mwifiex_sta_node *node;
 
-       if (!priv->media_connected || idx)
-               return -ENOENT;
+       if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+           priv->media_connected && idx == 0) {
+               ether_addr_copy(mac, priv->cfg_bssid);
+               return mwifiex_dump_station_info(priv, NULL, sinfo);
+       } else if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
+               mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST,
+                                HostCmd_ACT_GEN_GET, 0, NULL, true);
+
+               if (node && (&node->list == &priv->sta_list)) {
+                       node = NULL;
+                       return -ENOENT;
+               }
 
-       memcpy(mac, priv->cfg_bssid, ETH_ALEN);
+               node = list_prepare_entry(node, &priv->sta_list, list);
+               list_for_each_entry_continue(node, &priv->sta_list, list) {
+                       ether_addr_copy(mac, node->mac_addr);
+                       return mwifiex_dump_station_info(priv, node, sinfo);
+               }
+       }
 
-       return mwifiex_dump_station_info(priv, sinfo);
+       return -ENOENT;
 }
 
 static int
@@ -1295,7 +1405,7 @@ mwifiex_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
        struct mwifiex_chan_stats *pchan_stats = priv->adapter->chan_stats;
        enum ieee80211_band band;
 
-       dev_dbg(priv->adapter->dev, "dump_survey idx=%d\n", idx);
+       mwifiex_dbg(priv->adapter, DUMP, "dump_survey idx=%d\n", idx);
 
        memset(survey, 0, sizeof(struct survey_info));
 
@@ -1472,8 +1582,8 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
        struct mwifiex_adapter *adapter = priv->adapter;
 
        if (!priv->media_connected) {
-               dev_err(adapter->dev,
-                       "Can not set Tx data rate in disconnected state\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "Can not set Tx data rate in disconnected state\n");
                return -EINVAL;
        }
 
@@ -1556,17 +1666,20 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
        if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
-               wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "%s: bss_type mismatched\n", __func__);
                return -EINVAL;
        }
 
        if (!priv->bss_started) {
-               wiphy_err(wiphy, "%s: bss not started\n", __func__);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "%s: bss not started\n", __func__);
                return -EINVAL;
        }
 
        if (mwifiex_set_mgmt_ies(priv, data)) {
-               wiphy_err(wiphy, "%s: setting mgmt ies failed\n", __func__);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "%s: setting mgmt ies failed\n", __func__);
                return -EFAULT;
        }
 
@@ -1594,7 +1707,8 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
        if (!params->mac || is_broadcast_ether_addr(params->mac))
                return 0;
 
-       wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, params->mac);
+       mwifiex_dbg(priv->adapter, INFO, "%s: mac address %pM\n",
+                   __func__, params->mac);
 
        eth_zero_addr(deauth_mac);
 
@@ -1687,17 +1801,30 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
        mwifiex_abort_cac(priv);
 
        if (mwifiex_del_mgmt_ies(priv))
-               wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Failed to delete mgmt IEs!\n");
 
        priv->ap_11n_enabled = 0;
        memset(&priv->bss_cfg, 0, sizeof(priv->bss_cfg));
 
        if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
                             HostCmd_ACT_GEN_SET, 0, NULL, true)) {
-               wiphy_err(wiphy, "Failed to stop the BSS\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Failed to stop the BSS\n");
+               return -1;
+       }
+
+       if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
+                            HostCmd_ACT_GEN_SET, 0, NULL, true)) {
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Failed to reset BSS\n");
                return -1;
        }
 
+       if (netif_carrier_ok(priv->netdev))
+               netif_carrier_off(priv->netdev);
+       mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
+
        return 0;
 }
 
@@ -1751,12 +1878,13 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
                return -EINVAL;
        }
 
-       mwifiex_uap_set_channel(bss_cfg, params->chandef);
+       mwifiex_uap_set_channel(priv, bss_cfg, params->chandef);
        mwifiex_set_uap_rates(bss_cfg, params);
 
        if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
                kfree(bss_cfg);
-               wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Failed to parse secuirty parameters!\n");
                return -1;
        }
 
@@ -1775,20 +1903,25 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
 
        mwifiex_set_wmm_params(priv, bss_cfg, params);
 
+       if (mwifiex_is_11h_active(priv))
+               mwifiex_set_tpc_params(priv, bss_cfg, params);
+
        if (mwifiex_is_11h_active(priv) &&
            !cfg80211_chandef_dfs_required(wiphy, &params->chandef,
                                           priv->bss_mode)) {
-               dev_dbg(priv->adapter->dev, "Disable 11h extensions in FW\n");
+               mwifiex_dbg(priv->adapter, INFO,
+                           "Disable 11h extensions in FW\n");
                if (mwifiex_11h_activate(priv, false)) {
-                       dev_err(priv->adapter->dev,
-                               "Failed to disable 11h extensions!!");
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "Failed to disable 11h extensions!!");
                        return -1;
                }
-               priv->state_11h.is_11h_active = true;
+               priv->state_11h.is_11h_active = false;
        }
 
        if (mwifiex_config_start_uap(priv, bss_cfg)) {
-               wiphy_err(wiphy, "Failed to start AP\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Failed to start AP\n");
                kfree(bss_cfg);
                return -1;
        }
@@ -1796,6 +1929,10 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
        if (mwifiex_set_mgmt_ies(priv, &params->beacon))
                return -1;
 
+       if (!netif_carrier_ok(priv->netdev))
+               netif_carrier_on(priv->netdev);
+       mwifiex_wake_up_net_dev_queue(priv->netdev, priv->adapter);
+
        memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg));
        kfree(bss_cfg);
        return 0;
@@ -1816,8 +1953,9 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
        if (mwifiex_deauthenticate(priv, NULL))
                return -EFAULT;
 
-       wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
-               " reason code %d\n", priv->cfg_bssid, reason_code);
+       mwifiex_dbg(priv->adapter, MSG,
+                   "info: successfully disconnected from %pM:\t"
+                   "reason code %d\n", priv->cfg_bssid, reason_code);
 
        eth_zero_addr(priv->cfg_bssid);
        priv->hs2_enabled = false;
@@ -1864,8 +2002,10 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
                                  CFG80211_BSS_FTYPE_UNKNOWN,
                                  bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
                                  0, ie_buf, ie_len, 0, GFP_KERNEL);
-       cfg80211_put_bss(priv->wdev.wiphy, bss);
-       memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
+       if (bss) {
+               cfg80211_put_bss(priv->wdev.wiphy, bss);
+               ether_addr_copy(priv->cfg_bssid, bss_info.bssid);
+       }
 
        return 0;
 }
@@ -1899,13 +2039,13 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
 
        req_ssid.ssid_len = ssid_len;
        if (ssid_len > IEEE80211_MAX_SSID_LEN) {
-               dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
+               mwifiex_dbg(priv->adapter, ERROR, "invalid SSID - aborting\n");
                return -EINVAL;
        }
 
        memcpy(req_ssid.ssid, ssid, ssid_len);
        if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
-               dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
+               mwifiex_dbg(priv->adapter, ERROR, "invalid SSID - aborting\n");
                return -EINVAL;
        }
 
@@ -1959,9 +2099,9 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
 
        if (sme->key) {
                if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
-                       dev_dbg(priv->adapter->dev,
-                               "info: setting wep encryption"
-                               with key len %d\n", sme->key_len);
+                       mwifiex_dbg(priv->adapter, INFO,
+                                   "info: setting wep encryption\t"
+                                   "with key len %d\n", sme->key_len);
                        priv->wep_key_curr_index = sme->key_idx;
                        ret = mwifiex_set_encode(priv, NULL, sme->key,
                                                 sme->key_len, sme->key_idx,
@@ -1978,7 +2118,7 @@ done:
                if (is_scanning_required) {
                        /* Do specific SSID scanning */
                        if (mwifiex_request_scan(priv, &req_ssid)) {
-                               dev_err(priv->adapter->dev, "scan error\n");
+                               mwifiex_dbg(priv->adapter, ERROR, "scan error\n");
                                return -EFAULT;
                        }
                }
@@ -1997,15 +2137,15 @@ done:
 
                if (!bss) {
                        if (is_scanning_required) {
-                               dev_warn(priv->adapter->dev,
-                                        "assoc: requested bss not found in scan results\n");
+                               mwifiex_dbg(priv->adapter, WARN,
+                                           "assoc: requested bss not found in scan results\n");
                                break;
                        }
                        is_scanning_required = 1;
                } else {
-                       dev_dbg(priv->adapter->dev,
-                               "info: trying to associate to '%s' bssid %pM\n",
-                               (char *) req_ssid.ssid, bss->bssid);
+                       mwifiex_dbg(priv->adapter, MSG,
+                                   "info: trying to associate to '%s' bssid %pM\n",
+                                   (char *)req_ssid.ssid, bss->bssid);
                        memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
                        break;
                }
@@ -2041,26 +2181,29 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        int ret;
 
        if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
-               wiphy_err(wiphy,
-                         "%s: reject infra assoc request in non-STA role\n",
-                         dev->name);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: reject infra assoc request in non-STA role\n",
+                           dev->name);
                return -EINVAL;
        }
 
        if (priv->wdev.current_bss) {
-               wiphy_warn(wiphy, "%s: already connected\n", dev->name);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: already connected\n", dev->name);
                return -EALREADY;
        }
 
        if (adapter->surprise_removed || adapter->is_cmd_timedout) {
-               wiphy_err(wiphy,
-                         "%s: Ignore connection. Card removed or FW in bad state\n",
-                         dev->name);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: Ignore connection.\t"
+                           "Card removed or FW in bad state\n",
+                           dev->name);
                return -EFAULT;
        }
 
-       wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
-                 (char *) sme->ssid, sme->bssid);
+       mwifiex_dbg(adapter, INFO,
+                   "info: Trying to associate to %s and bssid %pM\n",
+                   (char *)sme->ssid, sme->bssid);
 
        ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
                                     priv->bss_mode, sme->channel, sme, 0);
@@ -2068,17 +2211,17 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
                                        NULL, 0, WLAN_STATUS_SUCCESS,
                                        GFP_KERNEL);
-               dev_dbg(priv->adapter->dev,
-                       "info: associated to bssid %pM successfully\n",
-                       priv->cfg_bssid);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "info: associated to bssid %pM successfully\n",
+                           priv->cfg_bssid);
                if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
                    priv->adapter->auto_tdls &&
                    priv->bss_type == MWIFIEX_BSS_TYPE_STA)
                        mwifiex_setup_auto_tdls_timer(priv);
        } else {
-               dev_dbg(priv->adapter->dev,
-                       "info: association to bssid %pM failed\n",
-                       priv->cfg_bssid);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "info: association to bssid %pM failed\n",
+                           priv->cfg_bssid);
                eth_zero_addr(priv->cfg_bssid);
 
                if (ret > 0)
@@ -2105,7 +2248,6 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
                                   struct cfg80211_ibss_params *params)
 {
-       struct wiphy *wiphy = priv->wdev.wiphy;
        struct mwifiex_adapter *adapter = priv->adapter;
        int index = 0, i;
        u8 config_bands = 0;
@@ -2162,8 +2304,10 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
        priv->adhoc_channel = ieee80211_frequency_to_channel(
                                params->chandef.chan->center_freq);
 
-       wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
-                 config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
+       mwifiex_dbg(adapter, INFO,
+                   "info: set ibss band %d, chan %d, chan offset %d\n",
+                   config_bands, priv->adhoc_channel,
+                   adapter->sec_chan_offset);
 
        return 0;
 }
@@ -2182,13 +2326,15 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        int ret = 0;
 
        if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
-               wiphy_err(wiphy, "request to join ibss received "
-                               "when station is not in ibss mode\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "request to join ibss received\t"
+                           "when station is not in ibss mode\n");
                goto done;
        }
 
-       wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
-                 (char *) params->ssid, params->bssid);
+       mwifiex_dbg(priv->adapter, MSG,
+                   "info: trying to join to %s and bssid %pM\n",
+                   (char *)params->ssid, params->bssid);
 
        mwifiex_set_ibss_params(priv, params);
 
@@ -2200,12 +2346,12 @@ done:
        if (!ret) {
                cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
                                     params->chandef.chan, GFP_KERNEL);
-               dev_dbg(priv->adapter->dev,
-                       "info: joined/created adhoc network with bssid"
-                       %pM successfully\n", priv->cfg_bssid);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "info: joined/created adhoc network with bssid\t"
+                           "%pM successfully\n", priv->cfg_bssid);
        } else {
-               dev_dbg(priv->adapter->dev,
-                       "info: failed creating/joining adhoc network\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "info: failed creating/joining adhoc network\n");
        }
 
        return ret;
@@ -2222,8 +2368,8 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
-       wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
-                 priv->cfg_bssid);
+       mwifiex_dbg(priv->adapter, MSG, "info: disconnecting from essid %pM\n",
+                   priv->cfg_bssid);
        if (mwifiex_deauthenticate(priv, NULL))
                return -EFAULT;
 
@@ -2236,7 +2382,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
  * CFG802.11 operation handler for scan request.
  *
  * This function issues a scan request to the firmware based upon
- * the user specified scan configuration. On successfull completion,
+ * the user specified scan configuration. On successful completion,
  * it also informs the results.
  */
 static int
@@ -2250,13 +2396,15 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
        struct ieee_types_header *ie;
        struct mwifiex_user_scan_cfg *user_scan_cfg;
 
-       wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
+       mwifiex_dbg(priv->adapter, CMD,
+                   "info: received scan request on %s\n", dev->name);
 
        /* Block scan request if scan operation or scan cleanup when interface
         * is disabled is in process
         */
        if (priv->scan_request || priv->scan_aborting) {
-               dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
+               mwifiex_dbg(priv->adapter, WARN,
+                           "cmd: Scan already in process..\n");
                return -EBUSY;
        }
 
@@ -2308,7 +2456,8 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
        ret = mwifiex_scan_networks(priv, user_scan_cfg);
        kfree(user_scan_cfg);
        if (ret) {
-               dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "scan failed: %d\n", ret);
                priv->scan_aborting = false;
                priv->scan_request = NULL;
                return ret;
@@ -2454,15 +2603,15 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
        case NL80211_IFTYPE_ADHOC:
                if (adapter->curr_iface_comb.sta_intf ==
                    adapter->iface_limit.sta_intf) {
-                       wiphy_err(wiphy,
-                                 "cannot create multiple sta/adhoc ifaces\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "cannot create multiple sta/adhoc ifaces\n");
                        return ERR_PTR(-EINVAL);
                }
 
                priv = mwifiex_get_unused_priv(adapter);
                if (!priv) {
-                       wiphy_err(wiphy,
-                                 "could not get free private struct\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "could not get free private struct\n");
                        return ERR_PTR(-EFAULT);
                }
 
@@ -2478,21 +2627,21 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
                priv->bss_priority = 0;
                priv->bss_role = MWIFIEX_BSS_ROLE_STA;
-               priv->bss_num = 0;
+               priv->bss_num = adapter->curr_iface_comb.sta_intf;
 
                break;
        case NL80211_IFTYPE_AP:
                if (adapter->curr_iface_comb.uap_intf ==
                    adapter->iface_limit.uap_intf) {
-                       wiphy_err(wiphy,
-                                 "cannot create multiple AP ifaces\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "cannot create multiple AP ifaces\n");
                        return ERR_PTR(-EINVAL);
                }
 
                priv = mwifiex_get_unused_priv(adapter);
                if (!priv) {
-                       wiphy_err(wiphy,
-                                 "could not get free private struct\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "could not get free private struct\n");
                        return ERR_PTR(-EFAULT);
                }
 
@@ -2504,22 +2653,22 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                priv->bss_priority = 0;
                priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
                priv->bss_started = 0;
-               priv->bss_num = 0;
+               priv->bss_num = adapter->curr_iface_comb.uap_intf;
                priv->bss_mode = type;
 
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
                if (adapter->curr_iface_comb.p2p_intf ==
                    adapter->iface_limit.p2p_intf) {
-                       wiphy_err(wiphy,
-                                 "cannot create multiple P2P ifaces\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "cannot create multiple P2P ifaces\n");
                        return ERR_PTR(-EINVAL);
                }
 
                priv = mwifiex_get_unused_priv(adapter);
                if (!priv) {
-                       wiphy_err(wiphy,
-                                 "could not get free private struct\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "could not get free private struct\n");
                        return ERR_PTR(-EFAULT);
                }
 
@@ -2540,7 +2689,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
                priv->bss_role = MWIFIEX_BSS_ROLE_STA;
                priv->bss_started = 0;
-               priv->bss_num = 0;
+               priv->bss_num = adapter->curr_iface_comb.p2p_intf;
 
                if (mwifiex_cfg80211_init_p2p_client(priv)) {
                        memset(&priv->wdev, 0, sizeof(priv->wdev));
@@ -2550,7 +2699,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 
                break;
        default:
-               wiphy_err(wiphy, "type not supported\n");
+               mwifiex_dbg(adapter, ERROR, "type not supported\n");
                return ERR_PTR(-EINVAL);
        }
 
@@ -2558,7 +2707,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                               name_assign_type, ether_setup,
                               IEEE80211_NUM_ACS, 1);
        if (!dev) {
-               wiphy_err(wiphy, "no memory available for netdevice\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "no memory available for netdevice\n");
                memset(&priv->wdev, 0, sizeof(priv->wdev));
                priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -2599,7 +2749,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 
        /* Register network device */
        if (register_netdevice(dev)) {
-               wiphy_err(wiphy, "cannot register virtual network device\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "cannot register virtual network device\n");
                free_netdev(dev);
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
                priv->netdev = NULL;
@@ -2613,7 +2764,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                                                  WQ_MEM_RECLAIM |
                                                  WQ_UNBOUND, 1, name);
        if (!priv->dfs_cac_workqueue) {
-               wiphy_err(wiphy, "cannot register virtual network device\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "cannot register virtual network device\n");
                free_netdev(dev);
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
                priv->netdev = NULL;
@@ -2628,7 +2780,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                                                      WQ_HIGHPRI | WQ_UNBOUND |
                                                      WQ_MEM_RECLAIM, 1, name);
        if (!priv->dfs_chan_sw_workqueue) {
-               wiphy_err(wiphy, "cannot register virtual network device\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "cannot register virtual network device\n");
                free_netdev(dev);
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
                priv->netdev = NULL;
@@ -2642,7 +2795,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 
        sema_init(&priv->async_sem, 1);
 
-       dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
+       mwifiex_dbg(adapter, INFO,
+                   "info: %s: Marvell 802.11 Adapter\n", dev->name);
 
 #ifdef CONFIG_DEBUG_FS
        mwifiex_dev_debugfs_init(priv);
@@ -2661,7 +2815,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                adapter->curr_iface_comb.p2p_intf++;
                break;
        default:
-               wiphy_err(wiphy, "type not supported\n");
+               mwifiex_dbg(adapter, ERROR, "type not supported\n");
                return ERR_PTR(-EINVAL);
        }
 
@@ -2676,6 +2830,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
        struct mwifiex_adapter *adapter = priv->adapter;
+       struct sk_buff *skb, *tmp;
 
 #ifdef CONFIG_DEBUG_FS
        mwifiex_dev_debugfs_remove(priv);
@@ -2683,6 +2838,9 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 
        mwifiex_stop_net_dev_queue(priv->netdev, adapter);
 
+       skb_queue_walk_safe(&priv->bypass_txq, skb, tmp)
+               mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+
        if (netif_carrier_ok(priv->netdev))
                netif_carrier_off(priv->netdev);
 
@@ -2711,17 +2869,18 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
        case NL80211_IFTYPE_UNSPECIFIED:
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_ADHOC:
-               adapter->curr_iface_comb.sta_intf++;
+               adapter->curr_iface_comb.sta_intf--;
                break;
        case NL80211_IFTYPE_AP:
-               adapter->curr_iface_comb.uap_intf++;
+               adapter->curr_iface_comb.uap_intf--;
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_P2P_GO:
-               adapter->curr_iface_comb.p2p_intf++;
+               adapter->curr_iface_comb.p2p_intf--;
                break;
        default:
-               dev_err(adapter->dev, "del_virtual_intf: type not supported\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "del_virtual_intf: type not supported\n");
                break;
        }
 
@@ -2839,8 +2998,8 @@ static int mwifiex_set_wowlan_mef_entry(struct mwifiex_private *priv,
                if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
                                        byte_seq,
                                        MWIFIEX_MEF_MAX_BYTESEQ)) {
-                       dev_err(priv->adapter->dev, "Pattern not supported\n");
-                       kfree(mef_entry);
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "Pattern not supported\n");
                        return -EOPNOTSUPP;
                }
 
@@ -2922,9 +3081,12 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
 
        mwifiex_set_auto_arp_mef_entry(priv, &mef_entry[0]);
 
-       if (wowlan->n_patterns || wowlan->magic_pkt)
+       if (wowlan->n_patterns || wowlan->magic_pkt) {
                ret = mwifiex_set_wowlan_mef_entry(priv, &mef_cfg,
                                                   &mef_entry[1], wowlan);
+               if (ret)
+                       goto err;
+       }
 
        if (!mef_cfg.criteria)
                mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
@@ -2934,6 +3096,8 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
        ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
                        HostCmd_ACT_GEN_SET, 0,
                        &mef_cfg, true);
+
+err:
        kfree(mef_entry);
        return ret;
 }
@@ -2954,21 +3118,22 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
        mwifiex_cancel_all_pending_cmd(adapter);
 
        if (!wowlan) {
-               dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "None of the WOWLAN triggers enabled\n");
                return 0;
        }
 
        priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
 
        if (!priv->media_connected) {
-               dev_warn(adapter->dev,
-                        "Can not configure WOWLAN in disconnected state\n");
+               mwifiex_dbg(adapter, ERROR,
+                           "Can not configure WOWLAN in disconnected state\n");
                return 0;
        }
 
        ret = mwifiex_set_mef_filter(priv, wowlan);
        if (ret) {
-               dev_err(adapter->dev, "Failed to set MEF filter\n");
+               mwifiex_dbg(adapter, ERROR, "Failed to set MEF filter\n");
                return ret;
        }
 
@@ -2981,7 +3146,8 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
                ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
                                            MWIFIEX_SYNC_CMD, &hs_cfg);
                if (ret) {
-                       dev_err(adapter->dev, "Failed to set HS params\n");
+                       mwifiex_dbg(adapter, ERROR,
+                                   "Failed to set HS params\n");
                        return ret;
                }
        }
@@ -3041,7 +3207,8 @@ mwifiex_fill_coalesce_rule_info(struct mwifiex_private *priv,
                if (!mwifiex_is_pattern_supported(&crule->patterns[i],
                                                  byte_seq,
                                                MWIFIEX_COALESCE_MAX_BYTESEQ)) {
-                       dev_err(priv->adapter->dev, "Pattern not supported\n");
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "Pattern not supported\n");
                        return -EOPNOTSUPP;
                }
 
@@ -3050,8 +3217,8 @@ mwifiex_fill_coalesce_rule_info(struct mwifiex_private *priv,
 
                        pkt_type = mwifiex_get_coalesce_pkt_type(byte_seq);
                        if (pkt_type && mrule->pkt_type) {
-                               dev_err(priv->adapter->dev,
-                                       "Multiple packet types not allowed\n");
+                               mwifiex_dbg(priv->adapter, ERROR,
+                                           "Multiple packet types not allowed\n");
                                return -EOPNOTSUPP;
                        } else if (pkt_type) {
                                mrule->pkt_type = pkt_type;
@@ -3074,8 +3241,8 @@ mwifiex_fill_coalesce_rule_info(struct mwifiex_private *priv,
        }
 
        if (!mrule->pkt_type) {
-               dev_err(priv->adapter->dev,
-                       "Packet type can not be determined\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Packet type can not be determined\n");
                return -EOPNOTSUPP;
        }
 
@@ -3093,8 +3260,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
 
        memset(&coalesce_cfg, 0, sizeof(coalesce_cfg));
        if (!coalesce) {
-               dev_dbg(adapter->dev,
-                       "Disable coalesce and reset all previous rules\n");
+               mwifiex_dbg(adapter, WARN,
+                           "Disable coalesce and reset all previous rules\n");
                return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
                                        HostCmd_ACT_GEN_SET, 0,
                                        &coalesce_cfg, true);
@@ -3105,8 +3272,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
                ret = mwifiex_fill_coalesce_rule_info(priv, &coalesce->rules[i],
                                                      &coalesce_cfg.rule[i]);
                if (ret) {
-                       dev_err(priv->adapter->dev,
-                               "Recheck the patterns provided for rule %d\n",
+                       mwifiex_dbg(adapter, ERROR,
+                                   "Recheck the patterns provided for rule %d\n",
                                i + 1);
                        return ret;
                }
@@ -3138,9 +3305,9 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
 
        switch (action_code) {
        case WLAN_TDLS_SETUP_REQUEST:
-               dev_dbg(priv->adapter->dev,
-                       "Send TDLS Setup Request to %pM status_code=%d\n", peer,
-                        status_code);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "Send TDLS Setup Request to %pM status_code=%d\n",
+                           peer, status_code);
                mwifiex_add_auto_tdls_peer(priv, peer);
                ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
                                                   dialog_token, status_code,
@@ -3148,45 +3315,45 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
                break;
        case WLAN_TDLS_SETUP_RESPONSE:
                mwifiex_add_auto_tdls_peer(priv, peer);
-               dev_dbg(priv->adapter->dev,
-                       "Send TDLS Setup Response to %pM status_code=%d\n",
-                       peer, status_code);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "Send TDLS Setup Response to %pM status_code=%d\n",
+                           peer, status_code);
                ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
                                                   dialog_token, status_code,
                                                   extra_ies, extra_ies_len);
                break;
        case WLAN_TDLS_SETUP_CONFIRM:
-               dev_dbg(priv->adapter->dev,
-                       "Send TDLS Confirm to %pM status_code=%d\n", peer,
-                       status_code);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "Send TDLS Confirm to %pM status_code=%d\n", peer,
+                           status_code);
                ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
                                                   dialog_token, status_code,
                                                   extra_ies, extra_ies_len);
                break;
        case WLAN_TDLS_TEARDOWN:
-               dev_dbg(priv->adapter->dev, "Send TDLS Tear down to %pM\n",
-                       peer);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "Send TDLS Tear down to %pM\n", peer);
                ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
                                                   dialog_token, status_code,
                                                   extra_ies, extra_ies_len);
                break;
        case WLAN_TDLS_DISCOVERY_REQUEST:
-               dev_dbg(priv->adapter->dev,
-                       "Send TDLS Discovery Request to %pM\n", peer);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "Send TDLS Discovery Request to %pM\n", peer);
                ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
                                                   dialog_token, status_code,
                                                   extra_ies, extra_ies_len);
                break;
        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
-               dev_dbg(priv->adapter->dev,
-                       "Send TDLS Discovery Response to %pM\n", peer);
+               mwifiex_dbg(priv->adapter, MSG,
+                           "Send TDLS Discovery Response to %pM\n", peer);
                ret = mwifiex_send_tdls_action_frame(priv, peer, action_code,
                                                   dialog_token, status_code,
                                                   extra_ies, extra_ies_len);
                break;
        default:
-               dev_warn(priv->adapter->dev,
-                        "Unknown TDLS mgmt/action frame %pM\n", peer);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Unknown TDLS mgmt/action frame %pM\n", peer);
                ret = -EINVAL;
                break;
        }
@@ -3208,8 +3375,8 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
        if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
                return -ENOTSUPP;
 
-       dev_dbg(priv->adapter->dev,
-               "TDLS peer=%pM, oper=%d\n", peer, action);
+       mwifiex_dbg(priv->adapter, MSG,
+                   "TDLS peer=%pM, oper=%d\n", peer, action);
 
        switch (action) {
        case NL80211_TDLS_ENABLE_LINK:
@@ -3220,28 +3387,94 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
                break;
        case NL80211_TDLS_TEARDOWN:
                /* shouldn't happen!*/
-               dev_warn(priv->adapter->dev,
-                        "tdls_oper: teardown from driver not supported\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "tdls_oper: teardown from driver not supported\n");
                return -EINVAL;
        case NL80211_TDLS_SETUP:
                /* shouldn't happen!*/
-               dev_warn(priv->adapter->dev,
-                        "tdls_oper: setup from driver not supported\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "tdls_oper: setup from driver not supported\n");
                return -EINVAL;
        case NL80211_TDLS_DISCOVERY_REQ:
                /* shouldn't happen!*/
-               dev_warn(priv->adapter->dev,
-                        "tdls_oper: discovery from driver not supported\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "tdls_oper: discovery from driver not supported\n");
                return -EINVAL;
        default:
-               dev_err(priv->adapter->dev,
-                       "tdls_oper: operation not supported\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "tdls_oper: operation not supported\n");
                return -ENOTSUPP;
        }
 
        return mwifiex_tdls_oper(priv, peer, action);
 }
 
+static int
+mwifiex_cfg80211_tdls_chan_switch(struct wiphy *wiphy, struct net_device *dev,
+                                 const u8 *addr, u8 oper_class,
+                                 struct cfg80211_chan_def *chandef)
+{
+       struct mwifiex_sta_node *sta_ptr;
+       unsigned long flags;
+       u16 chan;
+       u8 second_chan_offset, band;
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+       spin_lock_irqsave(&priv->sta_list_spinlock, flags);
+       sta_ptr = mwifiex_get_sta_entry(priv, addr);
+       spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
+
+       if (!sta_ptr) {
+               wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n",
+                         __func__, addr);
+               return -ENOENT;
+       }
+
+       if (!(sta_ptr->tdls_cap.extcap.ext_capab[3] &
+             WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH)) {
+               wiphy_err(wiphy, "%pM do not support tdls cs\n", addr);
+               return -ENOENT;
+       }
+
+       if (sta_ptr->tdls_status == TDLS_CHAN_SWITCHING ||
+           sta_ptr->tdls_status == TDLS_IN_OFF_CHAN) {
+               wiphy_err(wiphy, "channel switch is running, abort request\n");
+               return -EALREADY;
+       }
+
+       chan = chandef->chan->hw_value;
+       second_chan_offset = mwifiex_get_sec_chan_offset(chan);
+       band = chandef->chan->band;
+       mwifiex_start_tdls_cs(priv, addr, chan, second_chan_offset, band);
+
+       return 0;
+}
+
+static void
+mwifiex_cfg80211_tdls_cancel_chan_switch(struct wiphy *wiphy,
+                                        struct net_device *dev,
+                                        const u8 *addr)
+{
+       struct mwifiex_sta_node *sta_ptr;
+       unsigned long flags;
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+       spin_lock_irqsave(&priv->sta_list_spinlock, flags);
+       sta_ptr = mwifiex_get_sta_entry(priv, addr);
+       spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
+
+       if (!sta_ptr) {
+               wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n",
+                         __func__, addr);
+       } else if (!(sta_ptr->tdls_status == TDLS_CHAN_SWITCHING ||
+                    sta_ptr->tdls_status == TDLS_IN_BASE_CHAN ||
+                    sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)) {
+               wiphy_err(wiphy, "tdls chan switch not initialize by %pM\n",
+                         addr);
+       } else
+               mwifiex_stop_tdls_cs(priv, addr);
+}
+
 static int
 mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
                             const u8 *mac, struct station_parameters *params)
@@ -3268,8 +3501,8 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
        if (priv->adapter->scan_processing) {
-               dev_err(priv->adapter->dev,
-                       "radar detection: scan in process...\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "radar detection: scan in process...\n");
                return -EBUSY;
        }
 
@@ -3284,8 +3517,8 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                                           params->beacon_csa.tail,
                                           params->beacon_csa.tail_len);
        if (!chsw_ie) {
-               dev_err(priv->adapter->dev,
-                       "Could not parse channel switch announcement IE\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Could not parse channel switch announcement IE\n");
                return -EINVAL;
        }
 
@@ -3297,10 +3530,12 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
        }
 
        if (mwifiex_del_mgmt_ies(priv))
-               wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "Failed to delete mgmt IEs!\n");
 
        if (mwifiex_set_mgmt_ies(priv, &params->beacon_csa)) {
-               wiphy_err(wiphy, "%s: setting mgmt ies failed\n", __func__);
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "%s: setting mgmt ies failed\n", __func__);
                return -EFAULT;
        }
 
@@ -3314,6 +3549,45 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
+static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
+                                       struct wireless_dev *wdev,
+                                       struct cfg80211_chan_def *chandef)
+{
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
+       struct mwifiex_bssdescriptor *curr_bss;
+       struct ieee80211_channel *chan;
+       u8 second_chan_offset;
+       enum nl80211_channel_type chan_type;
+       enum ieee80211_band band;
+       int freq;
+       int ret = -ENODATA;
+
+       if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
+           cfg80211_chandef_valid(&priv->bss_chandef)) {
+               *chandef = priv->bss_chandef;
+               ret = 0;
+       } else if (priv->media_connected) {
+               curr_bss = &priv->curr_bss_params.bss_descriptor;
+               band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
+               freq = ieee80211_channel_to_frequency(curr_bss->channel, band);
+               chan = ieee80211_get_channel(wiphy, freq);
+
+               if (curr_bss->bcn_ht_oper) {
+                       second_chan_offset = curr_bss->bcn_ht_oper->ht_param &
+                                       IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+                       chan_type = mwifiex_sec_chan_offset_to_chan_type
+                                                       (second_chan_offset);
+                       cfg80211_chandef_create(chandef, chan, chan_type);
+               } else {
+                       cfg80211_chandef_create(chandef, chan,
+                                               NL80211_CHAN_NO_HT);
+               }
+               ret = 0;
+       }
+
+       return ret;
+}
+
 static int
 mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
                                       struct net_device *dev,
@@ -3324,16 +3598,17 @@ mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
        struct mwifiex_radar_params radar_params;
 
        if (priv->adapter->scan_processing) {
-               dev_err(priv->adapter->dev,
-                       "radar detection: scan already in process...\n");
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "radar detection: scan already in process...\n");
                return -EBUSY;
        }
 
        if (!mwifiex_is_11h_active(priv)) {
-               dev_dbg(priv->adapter->dev, "Enable 11h extensions in FW\n");
+               mwifiex_dbg(priv->adapter, INFO,
+                           "Enable 11h extensions in FW\n");
                if (mwifiex_11h_activate(priv, true)) {
-                       dev_err(priv->adapter->dev,
-                               "Failed to activate 11h extensions!!");
+                       mwifiex_dbg(priv->adapter, ERROR,
+                                   "Failed to activate 11h extensions!!");
                        return -1;
                }
                priv->state_11h.is_11h_active = true;
@@ -3416,8 +3691,11 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
        .set_coalesce = mwifiex_cfg80211_set_coalesce,
        .tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
        .tdls_oper = mwifiex_cfg80211_tdls_oper,
+       .tdls_channel_switch = mwifiex_cfg80211_tdls_chan_switch,
+       .tdls_cancel_channel_switch = mwifiex_cfg80211_tdls_cancel_chan_switch,
        .add_station = mwifiex_cfg80211_add_station,
        .change_station = mwifiex_cfg80211_change_station,
+       .get_channel = mwifiex_cfg80211_get_channel,
        .start_radar_detection = mwifiex_cfg80211_start_radar_detection,
        .channel_switch = mwifiex_cfg80211_channel_switch,
 };
@@ -3492,7 +3770,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
        wiphy = wiphy_new(&mwifiex_cfg80211_ops,
                          sizeof(struct mwifiex_adapter *));
        if (!wiphy) {
-               dev_err(adapter->dev, "%s: creating new wiphy\n", __func__);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: creating new wiphy\n", __func__);
                return -ENOMEM;
        }
        wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
@@ -3511,7 +3790,12 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
        else
                wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
 
-       wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
+       if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info))
+               wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs;
+       else if (adapter->is_hw_11ac_capable)
+               wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_vht;
+       else
+               wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
        wiphy->n_iface_combinations = 1;
 
        /* Initialize cipher suits */
@@ -3524,7 +3808,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
                        WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
                        WIPHY_FLAG_AP_UAPSD |
                        WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-                       WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+                       WIPHY_FLAG_HAS_CHANNEL_SWITCH |
+                       WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
        if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
                wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
@@ -3547,6 +3832,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
                           NL80211_FEATURE_INACTIVITY_TIMER |
                           NL80211_FEATURE_NEED_OBSS_SCAN;
 
+       if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
+               wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
+
        if (adapter->fw_api_ver == MWIFIEX_FW_V15)
                wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
 
@@ -3563,20 +3851,22 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 
        ret = wiphy_register(wiphy);
        if (ret < 0) {
-               dev_err(adapter->dev,
-                       "%s: wiphy_register failed: %d\n", __func__, ret);
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: wiphy_register failed: %d\n", __func__, ret);
                wiphy_free(wiphy);
                return ret;
        }
 
        if (reg_alpha2 && mwifiex_is_valid_alpha2(reg_alpha2)) {
-               wiphy_info(wiphy, "driver hint alpha2: %2.2s\n", reg_alpha2);
+               mwifiex_dbg(adapter, INFO,
+                           "driver hint alpha2: %2.2s\n", reg_alpha2);
                regulatory_hint(wiphy, reg_alpha2);
        } else {
                country_code = mwifiex_11d_code_2_region(adapter->region_code);
                if (country_code)
-                       wiphy_info(wiphy, "ignoring F/W country code %2.2s\n",
-                                  country_code);
+                       mwifiex_dbg(adapter, WARN,
+                                   "ignoring F/W country code %2.2s\n",
+                                   country_code);
        }
 
        mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,