iwlwifi: beacon format related helper function
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Thu, 6 May 2010 15:54:10 +0000 (08:54 -0700)
committerReinette Chatre <reinette.chatre@intel.com>
Sun, 6 Jun 2010 06:15:49 +0000 (23:15 -0700)
Move the ucode beacon formation related helper function from 3945 to
iwlcore, so both _3945 and _agn devices can utilize those functions.

When driver pass the beacon related timing information to uCode in both
spectrum measurement and channel switch commands, the beacon timing
parameter require in uCode beacon format; those helper functions will do
the conversation from uSec to the correct uCode format

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl3945-base.c

index 6be2992f8f210dbe3b0d0dee0b0c43ddd78efe94..dba91e0233b64df8b1cdd02640add02e9a0d0878 100644 (file)
@@ -158,6 +158,8 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
                        BIT(IWL_CALIB_TX_IQ_PERD)       |
                        BIT(IWL_CALIB_BASE_BAND);
 
+       priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
+
        return 0;
 }
 
index 7a34ef66c7ff71c1d1f974f13b13715c9e9fb2f6..295b67ac8169de7f3efeef1c98adb1b30d161081 100644 (file)
@@ -2433,6 +2433,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
 
        priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
        priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
+       priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS;
 
        return 0;
 }
index a0669ea427909cf431fbb56f549994a237ebf473..fe7aa73cc0eb65628e457676c9b307f1fb3dd1b3 100644 (file)
@@ -672,6 +672,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
                priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
 
        priv->hw_params.sens = &iwl4965_sensitivity;
+       priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
 
        return 0;
 }
index a28af7eb67eb464775369f7ff0617aed88847547..c320d4110fef7075400a180178ff0549782a023e 100644 (file)
@@ -208,6 +208,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_TX_IQ_PERD)       |
                BIT(IWL_CALIB_BASE_BAND);
 
+       priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
+
        return 0;
 }
 
@@ -252,6 +254,8 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_TX_IQ)            |
                BIT(IWL_CALIB_BASE_BAND);
 
+       priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
+
        return 0;
 }
 
index 73713f6a8df439b610b5c1d8913c21276147db67..5f6dbd9561d7d738270bdc5caa49eec29e5518b4 100644 (file)
@@ -187,6 +187,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_TX_IQ)            |
                BIT(IWL_CALIB_BASE_BAND);
 
+       priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
+
        return 0;
 }
 
@@ -232,6 +234,8 @@ static int iwl6050_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_TX_IQ)            |
                BIT(IWL_CALIB_BASE_BAND);
 
+       priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
+
        return 0;
 }
 
index 245cb906c39e21e5bd6263107a3dcde6b64d0e2b..b05b813413fd5882f441504572cdbfa9a7ce05ca 100644 (file)
@@ -2710,6 +2710,61 @@ void iwl_bg_monitor_recover(unsigned long data)
 }
 EXPORT_SYMBOL(iwl_bg_monitor_recover);
 
+
+/*
+ * extended beacon time format
+ * time in usec will be changed into a 32-bit value in extended:internal format
+ * the extended part is the beacon counts
+ * the internal part is the time in usec within one beacon interval
+ */
+u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval)
+{
+       u32 quot;
+       u32 rem;
+       u32 interval = beacon_interval * TIME_UNIT;
+
+       if (!interval || !usec)
+               return 0;
+
+       quot = (usec / interval) &
+               (iwl_beacon_time_mask_high(priv,
+               priv->hw_params.beacon_time_tsf_bits) >>
+               priv->hw_params.beacon_time_tsf_bits);
+       rem = (usec % interval) & iwl_beacon_time_mask_low(priv,
+                                  priv->hw_params.beacon_time_tsf_bits);
+
+       return (quot << priv->hw_params.beacon_time_tsf_bits) + rem;
+}
+EXPORT_SYMBOL(iwl_usecs_to_beacons);
+
+/* base is usually what we get from ucode with each received frame,
+ * the same as HW timer counter counting down
+ */
+__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
+                          u32 addon, u32 beacon_interval)
+{
+       u32 base_low = base & iwl_beacon_time_mask_low(priv,
+                                       priv->hw_params.beacon_time_tsf_bits);
+       u32 addon_low = addon & iwl_beacon_time_mask_low(priv,
+                                       priv->hw_params.beacon_time_tsf_bits);
+       u32 interval = beacon_interval * TIME_UNIT;
+       u32 res = (base & iwl_beacon_time_mask_high(priv,
+                               priv->hw_params.beacon_time_tsf_bits)) +
+                               (addon & iwl_beacon_time_mask_high(priv,
+                               priv->hw_params.beacon_time_tsf_bits));
+
+       if (base_low > addon_low)
+               res += base_low - addon_low;
+       else if (base_low < addon_low) {
+               res += interval + base_low - addon_low;
+               res += (1 << priv->hw_params.beacon_time_tsf_bits);
+       } else
+               res += (1 << priv->hw_params.beacon_time_tsf_bits);
+
+       return cpu_to_le32(res);
+}
+EXPORT_SYMBOL(iwl_add_beacon_time);
+
 #ifdef CONFIG_PM
 
 int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
index 69738f1e5416af5384be46c6acfed66017e81e38..48d96fda431c0e298ae1a06860bd1301cc0704bc 100644 (file)
@@ -79,6 +79,8 @@ struct iwl_cmd;
        .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
        .driver_data = (kernel_ulong_t)&(cfg)
 
+#define TIME_UNIT              1024
+
 #define IWL_SKU_G       0x1
 #define IWL_SKU_A       0x2
 #define IWL_SKU_N       0x8
@@ -591,6 +593,9 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
 }
 
 void iwl_bg_monitor_recover(unsigned long data);
+u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
+__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
+                          u32 addon, u32 beacon_interval);
 
 #ifdef CONFIG_PM
 int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
index 8b7731a9a20c5ddd9e640fad66496d1a66dffad2..6663df24a0c4e6f6ac7c4f81e1226dd1ca3cf11a 100644 (file)
@@ -662,6 +662,7 @@ struct iwl_sensitivity_ranges {
  * @sw_crypto: 0 for hw, 1 for sw
  * @max_xxx_size: for ucode uses
  * @ct_kill_threshold: temperature threshold
+ * @beacon_time_tsf_bits: number of valid tsf bits for beacon time
  * @calib_init_cfg: setup initial calibrations for the hw
  * @struct iwl_sensitivity_ranges: range of sensitivity values
  */
@@ -688,6 +689,7 @@ struct iwl_hw_params {
        u32 ct_kill_threshold; /* value in hw-dependent units */
        u32 ct_kill_exit_threshold; /* value in hw-dependent units */
                                    /* for 1000, 6000 series and up */
+       u16 beacon_time_tsf_bits;
        u32 calib_init_cfg;
        const struct iwl_sensitivity_ranges *sens;
 };
@@ -1062,6 +1064,20 @@ struct iwl_force_reset {
        unsigned long last_force_reset_jiffies;
 };
 
+/* extend beacon time format bit shifting  */
+/*
+ * for _3945 devices
+ * bits 31:24 - extended
+ * bits 23:0  - interval
+ */
+#define IWL3945_EXT_BEACON_TIME_POS    24
+/*
+ * for _agn devices
+ * bits 31:22 - extended
+ * bits 21:0  - interval
+ */
+#define IWLAGN_EXT_BEACON_TIME_POS     22
+
 struct iwl_priv {
 
        /* ieee device used by generic ieee processing code */
index 69846395763b5805b4554929ff3ae20668dd71a6..621abe3c5afce3fc2b73b66e37c82c7b4d8fcf66 100644 (file)
@@ -175,4 +175,26 @@ static inline void iwl_enable_interrupts(struct iwl_priv *priv)
        iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
 }
 
+/**
+ * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
+ * @priv -- pointer to iwl_priv data structure
+ * @tsf_bits -- number of bits need to shift for masking)
+ */
+static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
+                                          u16 tsf_bits)
+{
+       return (1 << tsf_bits) - 1;
+}
+
+/**
+ * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
+ * @priv -- pointer to iwl_priv data structure
+ * @tsf_bits -- number of bits need to shift for masking)
+ */
+static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
+                                           u16 tsf_bits)
+{
+       return ((1 << (32 - tsf_bits)) - 1) << tsf_bits;
+}
+
 #endif                         /* __iwl_helpers_h__ */
index f2ec752c669780c89700996a08f31c7c5c5587ac..eeeb6e8cd1de008c9cd73d770802227de3b80d6b 100644 (file)
@@ -665,55 +665,6 @@ drop:
        return -1;
 }
 
-#define BEACON_TIME_MASK_LOW   0x00FFFFFF
-#define BEACON_TIME_MASK_HIGH  0xFF000000
-#define TIME_UNIT              1024
-
-/*
- * extended beacon time format
- * time in usec will be changed into a 32-bit value in 8:24 format
- * the high 1 byte is the beacon counts
- * the lower 3 bytes is the time in usec within one beacon interval
- */
-
-static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval)
-{
-       u32 quot;
-       u32 rem;
-       u32 interval = beacon_interval * 1024;
-
-       if (!interval || !usec)
-               return 0;
-
-       quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
-       rem = (usec % interval) & BEACON_TIME_MASK_LOW;
-
-       return (quot << 24) + rem;
-}
-
-/* base is usually what we get from ucode with each received frame,
- * the same as HW timer counter counting down
- */
-
-static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
-{
-       u32 base_low = base & BEACON_TIME_MASK_LOW;
-       u32 addon_low = addon & BEACON_TIME_MASK_LOW;
-       u32 interval = beacon_interval * TIME_UNIT;
-       u32 res = (base & BEACON_TIME_MASK_HIGH) +
-           (addon & BEACON_TIME_MASK_HIGH);
-
-       if (base_low > addon_low)
-               res += base_low - addon_low;
-       else if (base_low < addon_low) {
-               res += interval + base_low - addon_low;
-               res += (1 << 24);
-       } else
-               res += (1 << 24);
-
-       return cpu_to_le32(res);
-}
-
 static int iwl3945_get_measurement(struct iwl_priv *priv,
                               struct ieee80211_measurement_params *params,
                               u8 type)
@@ -731,8 +682,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
        int duration = le16_to_cpu(params->duration);
 
        if (iwl_is_associated(priv))
-               add_time =
-                   iwl3945_usecs_to_beacons(
+               add_time = iwl_usecs_to_beacons(priv,
                        le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
                        le16_to_cpu(priv->rxon_timing.beacon_interval));
 
@@ -747,8 +697,8 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
 
        if (iwl_is_associated(priv))
                spectrum.start_time =
-                   iwl3945_add_beacon_time(priv->_3945.last_beacon_time,
-                               add_time,
+                       iwl_add_beacon_time(priv,
+                               priv->_3945.last_beacon_time, add_time,
                                le16_to_cpu(priv->rxon_timing.beacon_interval));
        else
                spectrum.start_time = 0;