For 6x00 2x2 NIC, two types of Power Amplifier are available.
In order for uCode to apply correct tx power,
driver needs to program the CSR_GP_DRIVER_REG register and
let uCode know the type of PA.
If driver do not program CSR_GP_DRIVER_REG register (default to 0),
then it is uCode's decision for tx power
2x2 Hybrid card: use both internal and external PA
2x2 IPA(Internal Power Amplifier) card: internal PA only
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
}
+/* NIC configuration for 1000 series */
+static void iwl1000_nic_config(struct iwl_priv *priv)
+{
+ iwl5000_nic_config(priv);
+
+ /* Setting digital SVR for 1000 card to 1.32V */
+ /* locking is acquired in iwl_set_bits_mask_prph() function */
+ iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
+ APMG_SVR_DIGITAL_VOLTAGE_1_32,
+ ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
+}
+
static struct iwl_lib_ops iwl1000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.init = iwl5000_apm_init,
.reset = iwl5000_apm_reset,
.stop = iwl5000_apm_stop,
- .config = iwl5000_nic_config,
+ .config = iwl1000_nic_config,
.set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
}
+/* NIC configuration for 5000 series and up */
void iwl5000_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
- if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_1000) {
- /* Setting digital SVR for 1000 card to 1.32V */
- iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
- APMG_SVR_DIGITAL_VOLTAGE_1_32,
- ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
- }
spin_unlock_irqrestore(&priv->lock, flags);
}
-
/*
* EEPROM
*/
priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
}
+/* NIC configuration for 6000 series */
+static void iwl6000_nic_config(struct iwl_priv *priv)
+{
+ iwl5000_nic_config(priv);
+
+ /* no locking required for register write */
+ if (priv->cfg->pa_type == IWL_PA_HYBRID) {
+ /* 2x2 hybrid phy type */
+ iwl_write32(priv, CSR_GP_DRIVER_REG,
+ CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB);
+ } else if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
+ /* 2x2 IPA phy type */
+ iwl_write32(priv, CSR_GP_DRIVER_REG,
+ CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
+ }
+ /* else do nothing, uCode configured */
+}
+
static struct iwl_lib_ops iwl6000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.init = iwl5000_apm_init,
.reset = iwl5000_apm_reset,
.stop = iwl5000_apm_stop,
- .config = iwl5000_nic_config,
+ .config = iwl6000_nic_config,
.set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
.valid_tx_ant = ANT_BC,
.valid_rx_ant = ANT_BC,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
-struct iwl_cfg iwl6000_2agn_cfg = {
+/*
+ * "h": Hybrid configuration, use both internal and external Power Amplifier
+ */
+struct iwl_cfg iwl6000h_2agn_cfg = {
.name = "6000 Series 2x2 AGN",
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.valid_tx_ant = ANT_AB,
.valid_rx_ant = ANT_AB,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_HYBRID,
+};
+
+/*
+ * "i": Internal configuration, use internal Power Amplifier
+ */
+struct iwl_cfg iwl6000i_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+ .pa_type = IWL_PA_INTERNAL,
};
struct iwl_cfg iwl6050_2agn_cfg = {
.valid_tx_ant = ANT_AB,
.valid_rx_ant = ANT_AB,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
struct iwl_cfg iwl6000_3agn_cfg = {
.valid_tx_ant = ANT_ABC,
.valid_rx_ant = ANT_ABC,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
struct iwl_cfg iwl6050_3agn_cfg = {
.valid_tx_ant = ANT_ABC,
.valid_rx_ant = ANT_ABC,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
{IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
{IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000h_2agn_cfg)},
{IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
{IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
* filename is constructed as fw_name_pre<api>.ucode.
* @ucode_api_max: Highest version of uCode API supported by driver.
* @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @pa_type: used by 6000 series only to identify the type of Power Amplifier
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
* iwl_hcmd_utils_ops etc. we accommodate different command structures
* and flows between hardware versions (4965/5000) as well as their API
* versions.
+ *
*/
struct iwl_cfg {
const char *name;
u8 valid_rx_ant;
bool need_pll_cfg;
bool use_isr_legacy;
+ enum iwl_pa_type pa_type;
};
/***************************
#define CSR_EEPROM_GP (CSR_BASE+0x030)
#define CSR_OTP_GP_REG (CSR_BASE+0x034)
#define CSR_GIO_REG (CSR_BASE+0x03C)
-#define CSR_GP_UCODE (CSR_BASE+0x044)
+#define CSR_GP_UCODE_REG (CSR_BASE+0x048)
+#define CSR_GP_DRIVER_REG (CSR_BASE+0x050)
#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
+/* GP Driver */
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK (0x00000003)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
+
+
/* GI Chicken Bits */
#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl6000_2ag_cfg;
-extern struct iwl_cfg iwl6000_2agn_cfg;
+extern struct iwl_cfg iwl6000h_2agn_cfg;
+extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_3agn_cfg;
NVM_DEVICE_TYPE_OTP,
};
+
+/**
+ * enum iwl_pa_type - Power Amplifier type
+ * @IWL_PA_SYSTEM: based on uCode configuration
+ * @IWL_PA_HYBRID: use both Internal and external PA
+ * @IWL_PA_INTERNAL: use Internal only
+ */
+enum iwl_pa_type {
+ IWL_PA_SYSTEM = 0,
+ IWL_PA_HYBRID = 1,
+ IWL_PA_INTERNAL = 2,
+};
+
/* interrupt statistics */
struct isr_statistics {
u32 hw;