Merge remote branch 'wireless-next/master' into ath6kl-next
authorKalle Valo <kvalo@qca.qualcomm.com>
Thu, 14 Jun 2012 11:20:18 +0000 (14:20 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 14 Jun 2012 11:44:49 +0000 (14:44 +0300)
Conflicts:
drivers/net/wireless/ath/ath6kl/cfg80211.c

1  2 
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/main.c

  
  #define DEFAULT_BG_SCAN_PERIOD 60
  
 +struct ath6kl_cfg80211_match_probe_ssid {
 +      struct cfg80211_ssid ssid;
 +      u8 flag;
 +};
 +
  static struct ieee80211_rate ath6kl_rates[] = {
        RATETAB_ENT(10, 0x1, 0),
        RATETAB_ENT(20, 0x2, 0),
@@@ -581,9 -576,6 +581,9 @@@ static int ath6kl_cfg80211_connect(stru
  
        vif->nw_type = vif->next_mode;
  
 +      /* enable enhanced bmiss detection if applicable */
 +      ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
 +
        if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
                nw_subtype = SUBTYPE_P2PCLIENT;
  
@@@ -860,6 -852,20 +860,6 @@@ void ath6kl_cfg80211_disconnect_event(s
                }
        }
  
 -      /*
 -       * Send a disconnect command to target when a disconnect event is
 -       * received with reason code other than 3 (DISCONNECT_CMD - disconnect
 -       * request from host) to make the firmware stop trying to connect even
 -       * after giving disconnect event. There will be one more disconnect
 -       * event for this disconnect command with reason code DISCONNECT_CMD
 -       * which will be notified to cfg80211.
 -       */
 -
 -      if (reason != DISCONNECT_CMD) {
 -              ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
 -              return;
 -      }
 -
        clear_bit(CONNECT_PEND, &vif->flags);
  
        if (vif->sme_state == SME_CONNECTING) {
                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
                                        GFP_KERNEL);
        } else if (vif->sme_state == SME_CONNECTED) {
 -              cfg80211_disconnected(vif->ndev, reason,
 +              cfg80211_disconnected(vif->ndev, proto_reason,
                                      NULL, 0, GFP_KERNEL);
        }
  
        vif->sme_state = SME_DISCONNECTED;
 +
 +      /*
 +       * Send a disconnect command to target when a disconnect event is
 +       * received with reason code other than 3 (DISCONNECT_CMD - disconnect
 +       * request from host) to make the firmware stop trying to connect even
 +       * after giving disconnect event. There will be one more disconnect
 +       * event for this disconnect command with reason code DISCONNECT_CMD
 +       * which won't be notified to cfg80211.
 +       */
 +      if (reason != DISCONNECT_CMD)
 +              ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
  }
  
  static int ath6kl_set_probed_ssids(struct ath6kl *ar,
                                   struct ath6kl_vif *vif,
 -                                 struct cfg80211_ssid *ssids, int n_ssids)
 +                                 struct cfg80211_ssid *ssids, int n_ssids,
 +                                 struct cfg80211_match_set *match_set,
 +                                 int n_match_ssid)
  {
 -      u8 i;
 +      u8 i, j, index_to_add, ssid_found = false;
 +      struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
 +
 +      memset(ssid_list, 0, sizeof(ssid_list));
  
 -      if (n_ssids > MAX_PROBED_SSID_INDEX)
 +      if (n_ssids > MAX_PROBED_SSIDS ||
 +          n_match_ssid > MAX_PROBED_SSIDS)
                return -EINVAL;
  
        for (i = 0; i < n_ssids; i++) {
 +              memcpy(ssid_list[i].ssid.ssid,
 +                     ssids[i].ssid,
 +                     ssids[i].ssid_len);
 +              ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
 +
 +              if (ssids[i].ssid_len)
 +                      ssid_list[i].flag = SPECIFIC_SSID_FLAG;
 +              else
 +                      ssid_list[i].flag = ANY_SSID_FLAG;
 +
 +              if (n_match_ssid == 0)
 +                      ssid_list[i].flag |= MATCH_SSID_FLAG;
 +      }
 +
 +      index_to_add = i;
 +
 +      for (i = 0; i < n_match_ssid; i++) {
 +              ssid_found = false;
 +
 +              for (j = 0; j < n_ssids; j++) {
 +                      if ((match_set[i].ssid.ssid_len ==
 +                           ssid_list[j].ssid.ssid_len) &&
 +                          (!memcmp(ssid_list[j].ssid.ssid,
 +                                   match_set[i].ssid.ssid,
 +                                   match_set[i].ssid.ssid_len))) {
 +                              ssid_list[j].flag |= MATCH_SSID_FLAG;
 +                              ssid_found = true;
 +                              break;
 +                      }
 +              }
 +
 +              if (ssid_found)
 +                      continue;
 +
 +              if (index_to_add >= MAX_PROBED_SSIDS)
 +                      continue;
 +
 +              ssid_list[index_to_add].ssid.ssid_len =
 +                      match_set[i].ssid.ssid_len;
 +              memcpy(ssid_list[index_to_add].ssid.ssid,
 +                     match_set[i].ssid.ssid,
 +                     match_set[i].ssid.ssid_len);
 +              ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
 +              index_to_add++;
 +      }
 +
 +      for (i = 0; i < index_to_add; i++) {
                ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 -                                        ssids[i].ssid_len ?
 -                                        SPECIFIC_SSID_FLAG : ANY_SSID_FLAG,
 -                                        ssids[i].ssid_len,
 -                                        ssids[i].ssid);
 +                                        ssid_list[i].flag,
 +                                        ssid_list[i].ssid.ssid_len,
 +                                        ssid_list[i].ssid.ssid);
 +
        }
  
        /* Make sure no old entries are left behind */
 -      for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) {
 +      for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
                ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
                                          DISABLE_SSID_FLAG, 0, NULL);
        }
@@@ -992,7 -934,7 +992,7 @@@ static int ath6kl_cfg80211_scan(struct 
        }
  
        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
 -                                    request->n_ssids);
 +                                    request->n_ssids, NULL, 0);
        if (ret < 0)
                return ret;
  
                                       WMI_FRAME_PROBE_REQ,
                                       request->ie, request->ie_len);
        if (ret) {
 -              ath6kl_err("failed to set Probe Request appie for scan");
 +              ath6kl_err("failed to set Probe Request appie for scan\n");
                return ret;
        }
  
@@@ -1570,9 -1512,6 +1570,9 @@@ static int ath6kl_cfg80211_change_iface
                }
        }
  
 +      /* need to clean up enhanced bmiss detection fw state */
 +      ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
 +
  set_iface_type:
        switch (type) {
        case NL80211_IFTYPE_STATION:
@@@ -2135,9 -2074,7 +2135,9 @@@ static int ath6kl_wow_suspend(struct at
        if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
                return -EINVAL;
  
 -      if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) {
 +      if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
 +          test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
 +                   ar->fw_capabilities)) {
                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
                                                vif->fw_vif_idx, false);
                if (ret)
@@@ -2272,9 -2209,7 +2272,9 @@@ static int ath6kl_wow_resume(struct ath
  
        ar->state = ATH6KL_STATE_ON;
  
 -      if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) {
 +      if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
 +          test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
 +                   ar->fw_capabilities)) {
                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
                                        vif->fw_vif_idx, true);
                if (ret)
@@@ -2540,7 -2475,7 +2540,7 @@@ void ath6kl_check_wow_status(struct ath
  static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
                            bool ht_enable)
  {
 -      struct ath6kl_htcap *htcap = &vif->htcap;
 +      struct ath6kl_htcap *htcap = &vif->htcap[band];
  
        if (htcap->ht_enable == ht_enable)
                return 0;
@@@ -2650,59 -2585,6 +2650,30 @@@ static int ath6kl_set_ies(struct ath6kl
        return 0;
  }
  
- static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
-                             struct ieee80211_channel *chan,
-                             enum nl80211_channel_type channel_type)
- {
-       struct ath6kl_vif *vif;
-       /*
-        * 'dev' could be NULL if a channel change is required for the hardware
-        * device itself, instead of a particular VIF.
-        *
-        * FIXME: To be handled properly when monitor mode is supported.
-        */
-       if (!dev)
-               return -EBUSY;
-       vif = netdev_priv(dev);
-       if (!ath6kl_cfg80211_ready(vif))
-               return -EIO;
-       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
-                  __func__, chan->center_freq, chan->hw_value);
-       vif->next_chan = chan->center_freq;
-       vif->next_ch_type = channel_type;
-       vif->next_ch_band = chan->band;
-       return 0;
- }
 +void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable)
 +{
 +      int err;
 +
 +      if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
 +              return;
 +
 +      if (vif->nw_type != INFRA_NETWORK)
 +              return;
 +
 +      if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
 +                    vif->ar->fw_capabilities))
 +              return;
 +
 +      ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
 +                 enable ? "enable" : "disable");
 +
 +      err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
 +                                             vif->fw_vif_idx, enable);
 +      if (err)
 +              ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
 +                         enable ? "enable" : "disable", err);
 +}
 +
  static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
                                u8 *rsn_capab)
  {
@@@ -2783,15 -2665,9 +2754,15 @@@ static int ath6kl_start_ap(struct wiph
  
        /* TODO:
         * info->interval
 -       * info->dtim_period
         */
  
 +      ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
 +                                       info->dtim_period);
 +
 +      /* ignore error, just print a warning and continue normally */
 +      if (ret)
 +              ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
 +
        if (info->beacon.head == NULL)
                return -EINVAL;
        mgmt = (struct ieee80211_mgmt *) info->beacon.head;
        p.ssid_len = vif->ssid_len;
        memcpy(p.ssid, vif->ssid, vif->ssid_len);
        p.dot11_auth_mode = vif->dot11_auth_mode;
-       p.ch = cpu_to_le16(vif->next_chan);
+       p.ch = cpu_to_le16(info->channel->center_freq);
  
        /* Enable uAPSD support by default */
        res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
                        return res;
        }
  
-       if (ath6kl_set_htcap(vif, vif->next_ch_band,
-                            vif->next_ch_type != NL80211_CHAN_NO_HT))
+       if (ath6kl_set_htcap(vif, info->channel->band,
+                            info->channel_type != NL80211_CHAN_NO_HT))
                return -EIO;
  
        /*
@@@ -3255,24 -3131,10 +3226,24 @@@ static int ath6kl_cfg80211_sscan_start(
        ath6kl_cfg80211_scan_complete_event(vif, true);
  
        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
 -                                    request->n_ssids);
 +                                    request->n_ssids,
 +                                    request->match_sets,
 +                                    request->n_match_sets);
        if (ret < 0)
                return ret;
  
 +      if (!request->n_match_sets) {
 +              ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 +                                             ALL_BSS_FILTER, 0);
 +              if (ret < 0)
 +                      return ret;
 +      } else {
 +               ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 +                                              MATCHED_SSID_FILTER, 0);
 +              if (ret < 0)
 +                      return ret;
 +      }
 +
        /* fw uses seconds, also make sure that it's >0 */
        interval = max_t(u16, 1, request->interval / 1000);
  
                                       WMI_FRAME_PROBE_REQ,
                                       request->ie, request->ie_len);
        if (ret) {
 -              ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
 +              ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
                            ret);
                return ret;
        }
@@@ -3326,18 -3188,6 +3297,18 @@@ static int ath6kl_cfg80211_sscan_stop(s
        return 0;
  }
  
 +static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
 +                                     struct net_device *dev,
 +                                     const u8 *addr,
 +                                     const struct cfg80211_bitrate_mask *mask)
 +{
 +      struct ath6kl *ar = ath6kl_priv(dev);
 +      struct ath6kl_vif *vif = netdev_priv(dev);
 +
 +      return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
 +                                         mask);
 +}
 +
  static const struct ieee80211_txrx_stypes
  ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
        [NL80211_IFTYPE_STATION] = {
@@@ -3392,7 -3242,6 +3363,6 @@@ static struct cfg80211_ops ath6kl_cfg80
        .suspend = __ath6kl_cfg80211_suspend,
        .resume = __ath6kl_cfg80211_resume,
  #endif
-       .set_channel = ath6kl_set_channel,
        .start_ap = ath6kl_start_ap,
        .change_beacon = ath6kl_change_beacon,
        .stop_ap = ath6kl_stop_ap,
        .mgmt_frame_register = ath6kl_mgmt_frame_register,
        .sched_scan_start = ath6kl_cfg80211_sscan_start,
        .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
 +      .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
  };
  
  void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
@@@ -3532,8 -3380,7 +3502,8 @@@ struct net_device *ath6kl_interface_add
        vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
        vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
        vif->bg_scan_period = 0;
 -      vif->htcap.ht_enable = true;
 +      vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true;
 +      vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
  
        memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
        if (fw_vif_idx != 0)
@@@ -3593,13 -3440,7 +3563,13 @@@ int ath6kl_cfg80211_init(struct ath6kl 
        }
  
        /* max num of ssids that can be probed during scanning */
 -      wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
 +      wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
 +
 +      /* max num of ssids that can be matched after scan */
 +      if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
 +                   ar->fw_capabilities))
 +              wiphy->max_match_sets = MAX_PROBED_SSIDS;
 +
        wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
        switch (ar->hw.cap) {
        case WMI_11AN_CAP:
                ath6kl_band_5ghz.ht_cap.cap = 0;
                ath6kl_band_5ghz.ht_cap.ht_supported = false;
        }
 +
 +      if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) {
 +              ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
 +              ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
 +              ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
 +              ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
 +      } else {
 +              ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
 +              ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
 +      }
 +
        if (band_2gig)
                wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
        if (band_5gig)
        wiphy->wowlan.pattern_min_len = 1;
        wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
  
 -      wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX;
 +      wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
  
        ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
                            WIPHY_FLAG_HAVE_AP_SME |
@@@ -100,21 -100,6 +100,21 @@@ enum ath6kl_fw_capability 
        /* Firmware has support to override rsn cap of rsn ie */
        ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
  
 +      /*
 +       * Multicast support in WOW and host awake mode.
 +       * Allow all multicast in host awake mode.
 +       * Apply multicast filter in WOW mode.
 +       */
 +      ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
 +
 +      /* Firmware supports enhanced bmiss detection */
 +      ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
 +
 +      /*
 +       * FW supports matching of ssid in schedule scan
 +       */
 +      ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
 +
        /* this needs to be last */
        ATH6KL_FW_CAPABILITY_MAX,
  };
@@@ -127,10 -112,6 +127,10 @@@ struct ath6kl_fw_ie 
        u8 data[0];
  };
  
 +enum ath6kl_hw_flags {
 +      ATH6KL_HW_FLAG_64BIT_RATES      = BIT(0),
 +};
 +
  #define ATH6KL_FW_API2_FILE "fw-2.bin"
  #define ATH6KL_FW_API3_FILE "fw-3.bin"
  
  
  #define AGGR_NUM_OF_FREE_NETBUFS    16
  
 -#define AGGR_RX_TIMEOUT     400       /* in ms */
 +#define AGGR_RX_TIMEOUT     100       /* in ms */
  
  #define WMI_TIMEOUT (2 * HZ)
  
@@@ -264,6 -245,7 +264,6 @@@ struct skb_hold_q 
  
  struct rxtid {
        bool aggr;
 -      bool progress;
        bool timer_mon;
        u16 win_sz;
        u16 seq_next;
        struct sk_buff_head q;
  
        /*
 -       * FIXME: No clue what this should protect. Apparently it should
 -       * protect some of the fields above but they are also accessed
 -       * without taking the lock.
 +       * lock mainly protects seq_next and hold_q. Movement of seq_next
 +       * needs to be protected between aggr_timeout() and
 +       * aggr_process_recv_frm(). hold_q will be holding the pending
 +       * reorder frames and it's access should also be protected.
 +       * Some of the other fields like hold_q_sz, win_sz and aggr are
 +       * initialized/reset when receiving addba/delba req, also while
 +       * deleting aggr state all the pending buffers are flushed before
 +       * resetting these fields, so there should not be any race in accessing
 +       * these fields.
         */
        spinlock_t lock;
  };
@@@ -565,7 -541,7 +565,7 @@@ struct ath6kl_vif 
        struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
        struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
        struct aggr_info *aggr_cntxt;
 -      struct ath6kl_htcap htcap;
 +      struct ath6kl_htcap htcap[IEEE80211_NUM_BANDS];
  
        struct timer_list disconnect_timer;
        struct timer_list sched_scan_timer;
        u32 last_cancel_roc_id;
        u32 send_action_id;
        bool probe_req_report;
-       u16 next_chan;
-       enum nl80211_channel_type next_ch_type;
-       enum ieee80211_band next_ch_band;
        u16 assoc_bss_beacon_int;
        u16 listen_intvl_t;
        u16 bmiss_time_t;
@@@ -711,8 -684,6 +708,8 @@@ struct ath6kl 
                u32 testscript_addr;
                enum wmi_phy_cap cap;
  
 +              u32 flags;
 +
                struct ath6kl_hw_fw {
                        const char *dir;
                        const char *otp;
@@@ -554,24 -554,20 +554,24 @@@ void ath6kl_ready_event(void *devt, u8 
        struct ath6kl *ar = devt;
  
        memcpy(ar->mac_addr, datap, ETH_ALEN);
 -      ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
 -                 __func__, ar->mac_addr);
 +
 +      ath6kl_dbg(ATH6KL_DBG_BOOT,
 +                 "ready event mac addr %pM sw_ver 0x%x abi_ver 0x%x cap 0x%x\n",
 +                 ar->mac_addr, sw_ver, abi_ver, cap);
  
        ar->version.wlan_ver = sw_ver;
        ar->version.abi_ver = abi_ver;
        ar->hw.cap = cap;
  
 -      snprintf(ar->wiphy->fw_version,
 -               sizeof(ar->wiphy->fw_version),
 -               "%u.%u.%u.%u",
 -               (ar->version.wlan_ver & 0xf0000000) >> 28,
 -               (ar->version.wlan_ver & 0x0f000000) >> 24,
 -               (ar->version.wlan_ver & 0x00ff0000) >> 16,
 -               (ar->version.wlan_ver & 0x0000ffff));
 +      if (strlen(ar->wiphy->fw_version) == 0) {
 +              snprintf(ar->wiphy->fw_version,
 +                       sizeof(ar->wiphy->fw_version),
 +                       "%u.%u.%u.%u",
 +                       (ar->version.wlan_ver & 0xf0000000) >> 28,
 +                       (ar->version.wlan_ver & 0x0f000000) >> 24,
 +                       (ar->version.wlan_ver & 0x00ff0000) >> 16,
 +                       (ar->version.wlan_ver & 0x0000ffff));
 +      }
  
        /* indicate to the waiting thread that the ready event was received */
        set_bit(WMI_READY, &ar->flag);
@@@ -602,7 -598,6 +602,6 @@@ static int ath6kl_commit_ch_switch(stru
  
        struct ath6kl *ar = vif->ar;
  
-       vif->next_chan = channel;
        vif->profile.ch = cpu_to_le16(channel);
  
        switch (vif->nw_type) {
@@@ -1171,10 -1166,7 +1170,10 @@@ static void ath6kl_set_multicast_list(s
        else
                clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
  
 -      mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
 +      if (test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
 +                   vif->ar->fw_capabilities)) {
 +              mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
 +      }
  
        if (!(ndev->flags & IFF_MULTICAST)) {
                mc_all_on = false;