iwlwifi: unify iwl_setup_rxon_timing
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / iwlwifi / iwl-core.c
index 11a19692f33ba3105a06d03bca2d5154d5fea0a9..7e528a0a15e3007e6de240ade54d789f024a9c69 100644 (file)
@@ -635,6 +635,63 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
 }
 EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
 
+static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
+{
+       u16 new_val = 0;
+       u16 beacon_factor = 0;
+
+       beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
+       new_val = beacon_val / beacon_factor;
+
+       if (!new_val)
+               new_val = max_beacon_val;
+
+       return new_val;
+}
+
+void iwl_setup_rxon_timing(struct iwl_priv *priv)
+{
+       u64 tsf;
+       s32 interval_tm, rem;
+       unsigned long flags;
+       struct ieee80211_conf *conf = NULL;
+       u16 beacon_int;
+
+       conf = ieee80211_get_hw_conf(priv->hw);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
+       priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
+
+       if (priv->iw_mode == NL80211_IFTYPE_STATION) {
+               beacon_int = priv->beacon_int;
+               priv->rxon_timing.atim_window = 0;
+       } else {
+               beacon_int = priv->vif->bss_conf.beacon_int;
+
+               /* TODO: we need to get atim_window from upper stack
+                * for now we set to 0 */
+               priv->rxon_timing.atim_window = 0;
+       }
+
+       beacon_int = iwl_adjust_beacon_interval(beacon_int,
+                               priv->hw_params.max_beacon_itrvl * 1024);
+       priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
+
+       tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
+       interval_tm = beacon_int * 1024;
+       rem = do_div(tsf, interval_tm);
+       priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       IWL_DEBUG_ASSOC(priv,
+                       "beacon interval %d beacon timer %d beacon tim %d\n",
+                       le16_to_cpu(priv->rxon_timing.beacon_interval),
+                       le32_to_cpu(priv->rxon_timing.beacon_init_val),
+                       le16_to_cpu(priv->rxon_timing.atim_window));
+}
+EXPORT_SYMBOL(iwl_setup_rxon_timing);
+
 void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
 {
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
@@ -1369,6 +1426,8 @@ int iwl_set_hw_params(struct iwl_priv *priv)
                priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K;
        priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256;
 
+       priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
+
        if (priv->cfg->mod_params->disable_11n)
                priv->cfg->sku &= ~IWL_SKU_N;