Merge branch 'for-linville' of git://github.com/kvalo/ath6kl
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 15 Feb 2013 19:06:32 +0000 (14:06 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 15 Feb 2013 19:06:32 +0000 (14:06 -0500)
1  2 
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/wmi.c

index a29f04e30830b46eadc366c39577ff6c14128488,ac0761c61ac1d62ad95258e6e4f8fbf23a523263..752ffc4f4166df35aaf782d7895ebb9e44fe3bdd
@@@ -427,6 -427,30 +427,30 @@@ static bool ath6kl_is_tx_pending(struc
        return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
  }
  
+ static 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_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                                   struct cfg80211_connect_params *sme)
                                        vif->req_bssid, vif->ch_hint,
                                        ar->connect_ctrl_flags, nw_subtype);
  
-       /* disable background scan if period is 0 */
-       if (sme->bg_scan_period == 0)
+       if (sme->bg_scan_period == 0) {
+               /* disable background scan if period is 0 */
                sme->bg_scan_period = 0xffff;
-       /* configure default value if not specified */
-       if (sme->bg_scan_period == -1)
+       } else if (sme->bg_scan_period == -1) {
+               /* configure default value if not specified */
                sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
+       }
  
        ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
                                  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
@@@ -767,7 -791,7 +791,7 @@@ void ath6kl_cfg80211_connect_event(stru
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
                           nw_type & ADHOC_CREATOR ? "creator" : "joiner");
                cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
 -              cfg80211_put_bss(bss);
 +              cfg80211_put_bss(ar->wiphy, bss);
                return;
        }
  
                                        assoc_req_ie, assoc_req_len,
                                        assoc_resp_ie, assoc_resp_len,
                                        WLAN_STATUS_SUCCESS, GFP_KERNEL);
 -              cfg80211_put_bss(bss);
 +              cfg80211_put_bss(ar->wiphy, bss);
        } else if (vif->sme_state == SME_CONNECTED) {
                /* inform roam event to cfg80211 */
                cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
  void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
                                      enum wmi_phy_mode mode)
  {
 -      enum nl80211_channel_type type;
 +      struct cfg80211_chan_def chandef;
  
        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
                   "channel switch notify nw_type %d freq %d mode %d\n",
                   vif->nw_type, freq, mode);
  
 -      type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT;
 +      cfg80211_chandef_create(&chandef,
 +                              ieee80211_get_channel(vif->ar->wiphy, freq),
 +                              (mode == WMI_11G_HT20) ?
 +                                      NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
  
 -      cfg80211_ch_switch_notify(vif->ndev, freq, type);
 +      cfg80211_ch_switch_notify(vif->ndev, &chandef);
  }
  
  static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@@ -1368,8 -1389,11 +1392,8 @@@ static int ath6kl_cfg80211_set_wiphy_pa
        return 0;
  }
  
 -/*
 - * The type nl80211_tx_power_setting replaces the following
 - * data type from 2.6.36 onwards
 -*/
  static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
 +                                     struct wireless_dev *wdev,
                                       enum nl80211_tx_power_setting type,
                                       int mbm)
  {
        return 0;
  }
  
 -static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
 +static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
 +                                     struct wireless_dev *wdev,
 +                                     int *dbm)
  {
        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
        struct ath6kl_vif *vif;
@@@ -1454,10 -1476,10 +1478,10 @@@ static int ath6kl_cfg80211_set_power_mg
                return -EIO;
  
        if (pmgmt) {
-               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
                mode.pwr_mode = REC_POWER;
        } else {
-               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
                mode.pwr_mode = MAX_PERF_POWER;
        }
  
@@@ -1509,7 -1531,7 +1533,7 @@@ static int ath6kl_cfg80211_del_iface(st
        list_del(&vif->list);
        spin_unlock_bh(&ar->list_lock);
  
-       ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
+       ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
  
        ath6kl_cfg80211_vif_cleanup(vif);
  
@@@ -1559,17 -1581,13 +1583,13 @@@ static int ath6kl_cfg80211_change_iface
  set_iface_type:
        switch (type) {
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_CLIENT:
                vif->next_mode = INFRA_NETWORK;
                break;
        case NL80211_IFTYPE_ADHOC:
                vif->next_mode = ADHOC_NETWORK;
                break;
        case NL80211_IFTYPE_AP:
-               vif->next_mode = AP_NETWORK;
-               break;
-       case NL80211_IFTYPE_P2P_CLIENT:
-               vif->next_mode = INFRA_NETWORK;
-               break;
        case NL80211_IFTYPE_P2P_GO:
                vif->next_mode = AP_NETWORK;
                break;
@@@ -1597,8 -1615,8 +1617,8 @@@ static int ath6kl_cfg80211_join_ibss(st
        vif->ssid_len = ibss_param->ssid_len;
        memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
  
 -      if (ibss_param->channel)
 -              vif->ch_hint = ibss_param->channel->center_freq;
 +      if (ibss_param->chandef.chan)
 +              vif->ch_hint = ibss_param->chandef.chan->center_freq;
  
        if (ibss_param->channel_fixed) {
                /*
@@@ -1778,14 -1796,14 +1798,14 @@@ static int ath6kl_get_station(struct wi
  
        if (vif->target_stats.rx_byte) {
                sinfo->rx_bytes = vif->target_stats.rx_byte;
 -              sinfo->filled |= STATION_INFO_RX_BYTES;
 +              sinfo->filled |= STATION_INFO_RX_BYTES64;
                sinfo->rx_packets = vif->target_stats.rx_pkt;
                sinfo->filled |= STATION_INFO_RX_PACKETS;
        }
  
        if (vif->target_stats.tx_byte) {
                sinfo->tx_bytes = vif->target_stats.tx_byte;
 -              sinfo->filled |= STATION_INFO_TX_BYTES;
 +              sinfo->filled |= STATION_INFO_TX_BYTES64;
                sinfo->tx_packets = vif->target_stats.tx_pkt;
                sinfo->filled |= STATION_INFO_TX_PACKETS;
        }
@@@ -2673,30 -2691,6 +2693,6 @@@ static int ath6kl_set_ies(struct ath6kl
        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)
  {
@@@ -2776,9 -2770,11 +2772,11 @@@ static int ath6kl_start_ap(struct wiph
  
        ar->ap_mode_bkey.valid = false;
  
-       /* TODO:
-        * info->interval
-        */
+       ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
+                                                info->beacon_interval);
+       if (ret)
+               ath6kl_warn("Failed to set beacon interval: %d\n", ret);
  
        ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
                                         info->dtim_period);
        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(info->channel->center_freq);
 +      p.ch = cpu_to_le16(info->chandef.chan->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, info->channel->band,
 -                           info->channel_type != NL80211_CHAN_NO_HT))
 +      if (ath6kl_set_htcap(vif, info->chandef.chan->band,
 +                           cfg80211_get_chandef_type(&info->chandef)
 +                                      != NL80211_CHAN_NO_HT))
                return -EIO;
  
        /*
@@@ -3010,6 -3005,7 +3008,6 @@@ static int ath6kl_change_station(struc
  static int ath6kl_remain_on_channel(struct wiphy *wiphy,
                                    struct wireless_dev *wdev,
                                    struct ieee80211_channel *chan,
 -                                  enum nl80211_channel_type channel_type,
                                    unsigned int duration,
                                    u64 *cookie)
  {
@@@ -3168,8 -3164,10 +3166,8 @@@ static bool ath6kl_is_p2p_go_ssid(cons
  
  static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                          struct ieee80211_channel *chan, bool offchan,
 -                        enum nl80211_channel_type channel_type,
 -                        bool channel_type_valid, unsigned int wait,
 -                        const u8 *buf, size_t len, bool no_cck,
 -                        bool dont_wait_for_ack, u64 *cookie)
 +                        unsigned int wait, const u8 *buf, size_t len,
 +                        bool no_cck, bool dont_wait_for_ack, u64 *cookie)
  {
        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
        struct ath6kl *ar = ath6kl_priv(vif->ndev);
@@@ -3492,8 -3490,8 +3490,8 @@@ void ath6kl_cfg80211_stop_all(struct at
                ath6kl_cfg80211_stop(vif);
  }
  
 -static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
 -                                    struct regulatory_request *request)
 +static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
 +                                     struct regulatory_request *request)
  {
        struct ath6kl *ar = wiphy_priv(wiphy);
        u32 rates[IEEE80211_NUM_BANDS];
                   request->processed ? " processed" : "",
                   request->initiator, request->user_reg_hint_type);
  
 -      /*
 -       * As firmware is not able intersect regdoms, we can only listen to
 -       * cellular hints.
 -       */
        if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
 -              return -EOPNOTSUPP;
 +              return;
  
        ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
        if (ret) {
                ath6kl_err("failed to set regdomain: %d\n", ret);
 -              return ret;
 +              return;
        }
  
        /*
        if (ret) {
                ath6kl_err("failed to start scan for a regdomain change: %d\n",
                           ret);
 -              return ret;
 +              return;
        }
 -
 -      return 0;
  }
  
  static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
        return 0;
  }
  
+ void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
+ {
+       static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+       bool discon_issued;
+       netif_stop_queue(vif->ndev);
+       clear_bit(WLAN_ENABLED, &vif->flags);
+       if (wmi_ready) {
+               discon_issued = test_bit(CONNECTED, &vif->flags) ||
+                               test_bit(CONNECT_PEND, &vif->flags);
+               ath6kl_disconnect(vif);
+               del_timer(&vif->disconnect_timer);
+               if (discon_issued)
+                       ath6kl_disconnect_event(vif, DISCONNECT_CMD,
+                                               (vif->nw_type & AP_NETWORK) ?
+                                               bcast_mac : vif->bssid,
+                                               0, NULL, 0);
+       }
+       if (vif->scan_req) {
+               cfg80211_scan_done(vif->scan_req, true);
+               vif->scan_req = NULL;
+       }
+       /* need to clean up enhanced bmiss detection fw state */
+       ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
+ }
  void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
  {
        struct ath6kl *ar = vif->ar;
index d366cf105c7c886a4aa1e78355fa47ec908a0680,a0503c2e7a7e4f50bc60955fa6563a9565ae91ac..d76b5bd81a0d50288633e6899ac9ba0f15f1746f
@@@ -474,7 -474,7 +474,7 @@@ static int ath6kl_wmi_remain_on_chnl_ev
                return -EINVAL;
        }
        id = vif->last_roc_id;
 -      cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT,
 +      cfg80211_ready_on_channel(&vif->wdev, id, chan,
                                  dur, GFP_ATOMIC);
  
        return 0;
@@@ -513,7 -513,8 +513,7 @@@ static int ath6kl_wmi_cancel_remain_on_
        else
                id = vif->last_roc_id; /* timeout on uncanceled r-o-c */
        vif->last_cancel_roc_id = 0;
 -      cfg80211_remain_on_channel_expired(&vif->wdev, id, chan,
 -                                         NL80211_CHAN_NO_HT, GFP_ATOMIC);
 +      cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, GFP_ATOMIC);
  
        return 0;
  }
@@@ -751,6 -752,23 +751,23 @@@ int ath6kl_wmi_force_roam_cmd(struct wm
                                   NO_SYNC_WMIFLAG);
  }
  
+ int ath6kl_wmi_ap_set_beacon_intvl_cmd(struct wmi *wmi, u8 if_idx,
+                                      u32 beacon_intvl)
+ {
+       struct sk_buff *skb;
+       struct set_beacon_int_cmd *cmd;
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+       cmd = (struct set_beacon_int_cmd *) skb->data;
+       cmd->beacon_intvl = cpu_to_le32(beacon_intvl);
+       return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+                                  WMI_SET_BEACON_INT_CMDID, NO_SYNC_WMIFLAG);
+ }
  int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period)
  {
        struct sk_buff *skb;
@@@ -1108,7 -1126,7 +1125,7 @@@ static int ath6kl_wmi_bssinfo_event_rx(
        kfree(mgmt);
        if (bss == NULL)
                return -ENOMEM;
 -      cfg80211_put_bss(bss);
 +      cfg80211_put_bss(ar->wiphy, bss);
  
        /*
         * Firmware doesn't return any event when scheduled scan has
@@@ -2480,16 -2498,11 +2497,11 @@@ static int ath6kl_wmi_sync_point(struc
  
  free_cmd_skb:
        /* free up any resources left over (possibly due to an error) */
-       if (skb)
-               dev_kfree_skb(skb);
+       dev_kfree_skb(skb);
  
  free_data_skb:
-       for (index = 0; index < num_pri_streams; index++) {
-               if (data_sync_bufs[index].skb != NULL) {
-                       dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
-                                     skb);
-               }
-       }
+       for (index = 0; index < num_pri_streams; index++)
+               dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].skb);
  
        return ret;
  }