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)
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.h
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/htc_pipe.c
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h

index a29f04e30830b46eadc366c39577ff6c14128488..752ffc4f4166df35aaf782d7895ebb9e44fe3bdd 100644 (file)
@@ -427,6 +427,30 @@ static bool ath6kl_is_tx_pending(struct ath6kl *ar)
        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)
@@ -616,13 +640,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                                        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);
@@ -1454,10 +1478,10 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
                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 +1533,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
        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 +1583,13 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
 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;
@@ -2673,30 +2693,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
        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 +2772,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
 
        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);
@@ -3557,6 +3555,37 @@ 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 e5e70f3a8ca866f1e4c1c40c8e9ff04914b49692..b59becd91aeaf9474728902a13db8bb899a0dc2a 100644 (file)
@@ -61,7 +61,5 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
 
 struct ath6kl *ath6kl_cfg80211_create(void);
 void ath6kl_cfg80211_destroy(struct ath6kl *ar);
-/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */
-void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable);
 
 #endif /* ATH6KL_CFG80211_H */
index 189d8faf8c87f8bd36b16d8d40e568aa90fc98f5..61b2f98b4e775afb9f0f4b17e4af8bed68baa59d 100644 (file)
@@ -940,7 +940,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
                         bool wait_fot_compltn, bool cold_reset);
 void ath6kl_init_control_info(struct ath6kl_vif *vif);
 struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
-void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
+void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready);
 int ath6kl_init_hw_start(struct ath6kl *ar);
 int ath6kl_init_hw_stop(struct ath6kl *ar);
 int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
index ba6bd497b78701f4d53a939b7343e766ca0088a0..281390178e3d9d062bb7c8afbf8e06de6364f39e 100644 (file)
@@ -509,9 +509,7 @@ static void destroy_htc_txctrl_packet(struct htc_packet *packet)
 {
        struct sk_buff *skb;
        skb = packet->skb;
-       if (skb != NULL)
-               dev_kfree_skb(skb);
-
+       dev_kfree_skb(skb);
        kfree(packet);
 }
 
@@ -969,6 +967,22 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
        u16 payload_len;
        int status = 0;
 
+       /*
+        * ar->htc_target can be NULL due to a race condition that can occur
+        * during driver initialization(we do 'ath6kl_hif_power_on' before
+        * initializing 'ar->htc_target' via 'ath6kl_htc_create').
+        * 'ath6kl_hif_power_on' assigns 'ath6kl_recv_complete' as
+        * usb_complete_t/callback function for 'usb_fill_bulk_urb'.
+        * Thus the possibility of ar->htc_target being NULL
+        * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work.
+        */
+       if (WARN_ON_ONCE(!target)) {
+               ath6kl_err("Target not yet initialized\n");
+               status = -EINVAL;
+               goto free_skb;
+       }
+
+
        netdata = skb->data;
        netlen = skb->len;
 
@@ -1054,6 +1068,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
 
                dev_kfree_skb(skb);
                skb = NULL;
+
                goto free_skb;
        }
 
@@ -1089,8 +1104,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
        skb = NULL;
 
 free_skb:
-       if (skb != NULL)
-               dev_kfree_skb(skb);
+       dev_kfree_skb(skb);
 
        return status;
 
@@ -1184,7 +1198,7 @@ static void reset_endpoint_states(struct htc_target *target)
                INIT_LIST_HEAD(&ep->pipe.tx_lookup_queue);
                INIT_LIST_HEAD(&ep->rx_bufq);
                ep->target = target;
-               ep->pipe.tx_credit_flow_enabled = (bool) 1; /* FIXME */
+               ep->pipe.tx_credit_flow_enabled = true;
        }
 }
 
index f21fa322e5ca3e7245a994ebce2dc0ce48c82c7a..5d434cf88f35adb52e4d28cd37cf7ea1cc2c50e0 100644 (file)
@@ -1715,38 +1715,6 @@ void ath6kl_init_hw_restart(struct ath6kl *ar)
        }
 }
 
-/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
-void ath6kl_cleanup_vif(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_stop_txrx(struct ath6kl *ar)
 {
        struct ath6kl_vif *vif, *tmp_vif;
@@ -1766,7 +1734,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
        list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
                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));
                rtnl_lock();
                ath6kl_cfg80211_vif_cleanup(vif);
                rtnl_unlock();
@@ -1801,8 +1769,6 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
                   "attempting to reset target on instance destroy\n");
        ath6kl_reset_device(ar, ar->target_type, true, true);
 
-       clear_bit(WLAN_ENABLED, &ar->flag);
-
        up(&ar->sem);
 }
 EXPORT_SYMBOL(ath6kl_stop_txrx);
index 62bcc0d5bc23d73493694984cd7e8aa202291635..5fcd342762dedfee03bfe899cd7dd2e3d2bd6382 100644 (file)
@@ -159,10 +159,8 @@ static void ath6kl_usb_free_urb_to_pipe(struct ath6kl_usb_pipe *pipe,
 
 static void ath6kl_usb_cleanup_recv_urb(struct ath6kl_urb_context *urb_context)
 {
-       if (urb_context->skb != NULL) {
-               dev_kfree_skb(urb_context->skb);
-               urb_context->skb = NULL;
-       }
+       dev_kfree_skb(urb_context->skb);
+       urb_context->skb = NULL;
 
        ath6kl_usb_free_urb_to_pipe(urb_context->pipe, urb_context);
 }
index d366cf105c7c886a4aa1e78355fa47ec908a0680..d76b5bd81a0d50288633e6899ac9ba0f15f1746f 100644 (file)
@@ -751,6 +751,23 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
                                   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;
@@ -2480,16 +2497,11 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
 
 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;
 }
index 98b1755e67f41f41f2af6f06ff6747731572aaca..b5f226503baf7e37ea15c7953878f7a05185375f 100644 (file)
@@ -1660,6 +1660,10 @@ struct roam_ctrl_cmd {
        u8 roam_ctrl;
 } __packed;
 
+struct set_beacon_int_cmd {
+       __le32 beacon_intvl;
+} __packed;
+
 struct set_dtim_cmd {
        __le32 dtim_period;
 } __packed;
@@ -2649,6 +2653,8 @@ int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
 int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi);
 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
 int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period);
+int ath6kl_wmi_ap_set_beacon_intvl_cmd(struct wmi *wmi, u8 if_idx,
+                                      u32 beacon_interval);
 int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
 int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
 int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);