/* calibrations defined for 5000 */
 /* defines the order in which results should be sent to the runtime uCode */
 enum iwl5000_calib {
+       IWL5000_CALIB_XTAL,
        IWL5000_CALIB_LO,
        IWL5000_CALIB_TX_IQ,
        IWL5000_CALIB_TX_IQ_PERD,
 
 /*
  *  Calibration
  */
-static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
+static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
 {
+       u8 data[sizeof(struct iwl5000_calib_hdr) +
+               sizeof(struct iwl_cal_xtal_freq)];
+       struct iwl5000_calib_cmd *cmd = (struct iwl5000_calib_cmd *)data;
+       struct iwl_cal_xtal_freq *xtal = (struct iwl_cal_xtal_freq *)cmd->data;
        u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
 
-       struct iwl5000_calibration cal_cmd = {
-               .op_code = IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD,
-               .data = {
-                       (u8)xtal_calib[0],
-                       (u8)xtal_calib[1],
-               }
-       };
-
-       return iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
-                               sizeof(cal_cmd), &cal_cmd);
+       cmd->hdr.op_code = IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
+       xtal->cap_pin1 = (u8)xtal_calib[0];
+       xtal->cap_pin2 = (u8)xtal_calib[1];
+       return iwl_calib_set(&priv->calib_results[IWL5000_CALIB_XTAL],
+                            data, sizeof(data));
 }
 
 static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
 
        iwl5000_send_wimax_coex(priv);
 
-       iwl5000_send_Xtal_calib(priv);
-
-       if (priv->ucode_type == UCODE_RT)
-               iwl_send_calib_results(priv);
+       iwl5000_set_Xtal_calib(priv);
+       iwl_send_calib_results(priv);
 
        return 0;
 }
                break;
        }
 
+       /* Set initial calibration set */
+       switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+       case CSR_HW_REV_TYPE_5100:
+       case CSR_HW_REV_TYPE_5300:
+       case CSR_HW_REV_TYPE_5350:
+               priv->hw_params.calib_init_cfg =
+                       BIT(IWL5000_CALIB_XTAL)         |
+                       BIT(IWL5000_CALIB_LO)           |
+                       BIT(IWL5000_CALIB_TX_IQ)        |
+                       BIT(IWL5000_CALIB_TX_IQ_PERD);
+               break;
+       case CSR_HW_REV_TYPE_5150:
+               priv->hw_params.calib_init_cfg = 0;
+               break;
+       }
+
+
        return 0;
 }
 
 
  * INIT calibrations framework
  *****************************************************************************/
 
- int iwl_send_calib_results(struct iwl_priv *priv)
+int iwl_send_calib_results(struct iwl_priv *priv)
 {
        int ret = 0;
        int i = 0;
                .meta.flags = CMD_SIZE_HUGE,
        };
 
-       for (i = 0; i < IWL_CALIB_MAX; i++)
-               if (priv->calib_results[i].buf) {
+       for (i = 0; i < IWL_CALIB_MAX; i++) {
+               if ((BIT(i) & priv->hw_params.calib_init_cfg) &&
+                   priv->calib_results[i].buf) {
                        hcmd.len = priv->calib_results[i].buf_len;
                        hcmd.data = priv->calib_results[i].buf;
                        ret = iwl_send_cmd_sync(priv, &hcmd);
                        if (ret)
                                goto err;
                }
+       }
 
        return 0;
 err:
 
        COEX_MEDIUM_NOTIFICATION = 0x5b,
        COEX_EVENT_CMD = 0x5c,
 
+       /* Calibration */
+       CALIBRATION_CFG_CMD = 0x65,
+       CALIBRATION_RES_NOTIFICATION = 0x66,
+       CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
+
        /* 802.11h related */
        RADAR_NOTIFICATION = 0x70,      /* not used */
        REPLY_QUIET_CMD = 0x71,         /* not used */
        IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19,
 };
 
-enum {
-       CALIBRATION_CFG_CMD = 0x65,
-       CALIBRATION_RES_NOTIFICATION = 0x66,
-       CALIBRATION_COMPLETE_NOTIFICATION = 0x67
-};
-
-struct iwl_cal_crystal_freq_cmd {
+struct iwl_cal_xtal_freq {
        u8 cap_pin1;
        u8 cap_pin2;
 } __attribute__ ((packed));
 
-struct iwl5000_calibration {
-       u8 op_code;
-       u8 first_group;
-       u8 num_groups;
-       u8 all_data_valid;
-       struct iwl_cal_crystal_freq_cmd data;
-} __attribute__ ((packed));
-
 #define IWL_CALIB_INIT_CFG_ALL __constant_cpu_to_le32(0xffffffff)
 
 struct iwl_calib_cfg_elmnt_s {
        u8 data_valid;
 } __attribute__ ((packed));
 
+struct iwl5000_calib_cmd {
+       struct iwl5000_calib_hdr hdr;
+       u8 data[0];
+} __attribute__ ((packed));
+
 struct iwl5000_calibration_chain_noise_reset_cmd {
        u8 op_code;     /* IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
        u8 flags;       /* not used */
                struct iwl_notif_statistics stats;
                struct iwl_compressed_ba_resp compressed_ba;
                struct iwl4965_missed_beacon_notif missed_beacon;
-               struct iwl5000_calibration calib;
                __le32 status;
                u8 raw[0];
        } u;
 
  * @sw_crypto: 0 for hw, 1 for sw
  * @max_xxx_size: for ucode uses
  * @ct_kill_threshold: temperature threshold
+ * @calib_init_cfg: setup initial claibrations for the hw
  * @struct iwl_sensitivity_ranges: range of sensitivity values
  * @first_ampdu_q: first HW queue available for ampdu
  */
        u32 max_data_size;
        u32 max_bsm_size;
        u32 ct_kill_threshold; /* value in hw-dependent units */
+       u32 calib_init_cfg;
        const struct iwl_sensitivity_ranges *sens;
        u8 first_ampdu_q;
 };
 
 
 #define IWL_MAX_NUM_QUEUES     20 /* FIXME: do dynamic allocation */
-#define IWL_CALIB_MAX  3
+#define IWL_CALIB_MAX  4
 
 struct iwl_priv {