ath6kl: Configure inactivity timeout in fw
authorVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Wed, 21 Mar 2012 15:28:39 +0000 (20:58 +0530)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 26 Mar 2012 13:28:39 +0000 (16:28 +0300)
Configure the inactivity timeout passed in start_ap() to
firmware. This capability is advertised only when fw supports
it, there is a new bit (ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT)
in firmware capability ie for driver to learn fw's capability.
After the fw finds out the station is inactive, it will probe
the station with null func frames. By default, the timeout is
10 secs.

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h

index 80910286d1b8b99e4bb5a14c3514bfe24c60442c..df95e0d9d70853ab459a7d3e4e5306b6e45180a6 100644 (file)
@@ -2617,6 +2617,13 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
                p.nw_subtype = SUBTYPE_NONE;
        }
 
+       if (info->inactivity_timeout) {
+               res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
+                                                 info->inactivity_timeout);
+               if (res < 0)
+                       return res;
+       }
+
        res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
        if (res < 0)
                return res;
@@ -3283,6 +3290,10 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
                ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
 
+       if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
+                    ar->fw_capabilities))
+               ar->wiphy->features = NL80211_FEATURE_INACTIVITY_TIMER;
+
        ar->wiphy->probe_resp_offload =
                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
index 17697eb054fa57a7e3f48f86c43f86bf219e3111..a29a3494dcc5422cda3d8eb46affb8ff878bb4e0 100644 (file)
@@ -91,6 +91,12 @@ enum ath6kl_fw_capability {
         */
        ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
 
+       /*
+        * Firmware has support to cleanup inactive stations
+        * in AP mode.
+        */
+       ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
+
        /* this needs to be last */
        ATH6KL_FW_CAPABILITY_MAX,
 };
index 7654e8e286d3ccb436c0b790492141073dca523c..b1b1f347a118b8318266c5695e9fa858bf4ea72a 100644 (file)
@@ -3395,6 +3395,23 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx)
                                     WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
 }
 
+int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout)
+{
+       struct sk_buff *skb;
+       struct wmi_set_inact_period_cmd *cmd;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_inact_period_cmd *) skb->data;
+       cmd->inact_period = cpu_to_le32(inact_timeout);
+       cmd->num_null_func = 0;
+
+       return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_CONN_INACT_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
 static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
 {
        struct wmix_cmd_hdr *cmd;
index 4092e3e80790f6d4ee58672c56e66d87f6f81f38..8c8a92258517125dbe02523a83d5f05ea4ef14fd 100644 (file)
@@ -2141,6 +2141,11 @@ struct wmi_ap_hidden_ssid_cmd {
        u8 hidden_ssid;
 } __packed;
 
+struct wmi_set_inact_period_cmd {
+       __le32 inact_period;
+       u8 num_null_func;
+} __packed;
+
 /* AP mode events */
 struct wmi_ap_set_apsd_cmd {
        u8 enable;
@@ -2538,6 +2543,8 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);
 int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
                             const u8 *ie, u8 ie_len);
 
+int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout);
+
 void ath6kl_wmi_sscan_timer(unsigned long ptr);
 
 struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);