ath6kl: enable enhanced bmiss detection
authorThomas Pedersen <c_tpeder@qca.qualcomm.com>
Tue, 15 May 2012 07:09:23 +0000 (00:09 -0700)
committerKalle Valo <kvalo@qca.qualcomm.com>
Wed, 16 May 2012 13:20:58 +0000 (16:20 +0300)
Enable enhanced bmiss detection if the firmware supports it. This
feature is only enabled on some firmwares since it comes with a power
cost.

Also add a few missing command ids to keep the enums straight.

kvalo: fix a compiler with ath6kl_err(), add few empty lines

Signed-off-by: Thomas Pedersen <c_tpeder@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
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/init.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h

index 22843a1..e68b107 100644 (file)
@@ -576,6 +576,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 
        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;
 
@@ -1512,6 +1515,9 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
                }
        }
 
+       /* 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:
@@ -2618,6 +2624,30 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
        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)
 {
index 5ea8cbb..b992046 100644 (file)
@@ -62,5 +62,7 @@ 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 79c7055..9916979 100644 (file)
@@ -107,6 +107,9 @@ enum ath6kl_fw_capability {
         */
        ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
 
+       /* Firmware supports enhanced bmiss detection */
+       ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
+
        /* this needs to be last */
        ATH6KL_FW_CAPABILITY_MAX,
 };
index 7eb0515..10de132 100644 (file)
@@ -1659,6 +1659,9 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
                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)
index bdd3b2c..6ad762d 100644 (file)
@@ -2997,6 +2997,25 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
        return ret;
 }
 
+int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance)
+{
+       struct sk_buff *skb;
+       struct wmi_sta_bmiss_enhance_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_sta_bmiss_enhance_cmd *) skb->data;
+       cmd->enable = enhance ? 1 : 0;
+
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+                                 WMI_STA_BMISS_ENHANCE_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
 s32 ath6kl_wmi_get_rate(s8 rate_index)
 {
        if (rate_index == RATE_AUTO)
index 3518550..8c07e38 100644 (file)
@@ -624,6 +624,10 @@ enum wmi_cmd_id {
        WMI_SEND_MGMT_CMDID,
        WMI_BEGIN_SCAN_CMDID,
 
+       WMI_SET_BLACK_LIST,
+       WMI_SET_MCASTRATE,
+
+       WMI_STA_BMISS_ENHANCE_CMDID,
 };
 
 enum wmi_mgmt_frame_type {
@@ -1017,6 +1021,11 @@ struct wmi_bmiss_time_cmd {
        __le16 num_beacons;
 };
 
+/* WMI_STA_ENHANCE_BMISS_CMDID */
+struct wmi_sta_bmiss_enhance_cmd {
+       u8 enable;
+} __packed;
+
 /* WMI_SET_POWER_MODE_CMDID */
 enum wmi_power_mode {
        REC_POWER = 0x01,
@@ -2547,6 +2556,8 @@ 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);
 int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
                                        u8 *filter, bool add_filter);
+int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
+
 /* AP mode uAPSD */
 int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);