if_iwm - Configure the PCIe LTR, fix PCI express capability accesses.
Taken-From: Linux iwlwifi Submitted by: Augustin Cavalier <waddlesplash@gmail.com> (Haiku) Obtained from: DragonFlyBSD (08a7ad5a5ff65aaaf2df6a609be7a4e1df43efc3)
This commit is contained in:
parent
27898346e2
commit
9612bbf423
@ -320,6 +320,7 @@ static int iwm_send_phy_cfg_cmd(struct iwm_softc *);
|
||||
static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
|
||||
enum iwm_ucode_type);
|
||||
static int iwm_run_init_mvm_ucode(struct iwm_softc *, int);
|
||||
static int iwm_mvm_config_ltr(struct iwm_softc *sc);
|
||||
static int iwm_rx_addbuf(struct iwm_softc *, int, int);
|
||||
static int iwm_mvm_get_signal_strength(struct iwm_softc *,
|
||||
struct iwm_rx_phy_info *);
|
||||
@ -3000,6 +3001,19 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mvm_config_ltr(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_ltr_config_cmd cmd = {
|
||||
.flags = htole32(IWM_LTR_CFG_FLAG_FEATURE_ENABLE),
|
||||
};
|
||||
|
||||
if (!sc->sc_ltr_enabled)
|
||||
return 0;
|
||||
|
||||
return iwm_mvm_send_cmd_pdu(sc, IWM_LTR_CONFIG, 0, sizeof(cmd), &cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* receive side
|
||||
*/
|
||||
@ -4665,6 +4679,9 @@ iwm_init_hw(struct iwm_softc *sc)
|
||||
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000)
|
||||
iwm_mvm_tt_tx_backoff(sc, 0);
|
||||
|
||||
if (iwm_mvm_config_ltr(sc) != 0)
|
||||
device_printf(sc->sc_dev, "PCIe LTR configuration failed\n");
|
||||
|
||||
error = iwm_mvm_power_update_device(sc);
|
||||
if (error)
|
||||
goto error;
|
||||
@ -5292,6 +5309,7 @@ iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m)
|
||||
case IWM_MAC_CONTEXT_CMD:
|
||||
case IWM_REPLY_SF_CFG_CMD:
|
||||
case IWM_POWER_TABLE_CMD:
|
||||
case IWM_LTR_CONFIG:
|
||||
case IWM_PHY_CONTEXT_CMD:
|
||||
case IWM_BINDING_CONTEXT_CMD:
|
||||
case IWM_TIME_EVENT_CMD:
|
||||
|
@ -406,18 +406,39 @@ iwm_prepare_card_hw(struct iwm_softc *sc)
|
||||
void
|
||||
iwm_apm_config(struct iwm_softc *sc)
|
||||
{
|
||||
uint16_t reg;
|
||||
uint16_t lctl, cap;
|
||||
int pcie_ptr;
|
||||
|
||||
reg = pci_read_config(sc->sc_dev, PCIER_LINK_CTL, sizeof(reg));
|
||||
if (reg & PCIEM_LINK_CTL_ASPMC_L1) {
|
||||
/* Um the Linux driver prints "Disabling L0S for this one ... */
|
||||
/*
|
||||
* HW bug W/A for instability in PCIe bus L0S->L1 transition.
|
||||
* Check if BIOS (or OS) enabled L1-ASPM on this device.
|
||||
* If so (likely), disable L0S, so device moves directly L0->L1;
|
||||
* costs negligible amount of power savings.
|
||||
* If not (unlikely), enable L0S, so there is at least some
|
||||
* power savings, even without L1.
|
||||
*/
|
||||
int error;
|
||||
|
||||
error = pci_find_cap(sc->sc_dev, PCIY_EXPRESS, &pcie_ptr);
|
||||
if (error != 0)
|
||||
return;
|
||||
lctl = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_LINK_CTL,
|
||||
sizeof(lctl));
|
||||
if (lctl & PCIEM_LINK_CTL_ASPMC_L1) {
|
||||
IWM_SETBITS(sc, IWM_CSR_GIO_REG,
|
||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||
} else {
|
||||
/* ... and "Enabling" here */
|
||||
IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
|
||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||
}
|
||||
|
||||
cap = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_DEVICE_CTL2,
|
||||
sizeof(cap));
|
||||
sc->sc_ltr_enabled = (cap & PCIEM_CTL2_LTR_ENABLE) ? 1 : 0;
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_PWRSAVE,
|
||||
"L1 %sabled - LTR %sabled\n",
|
||||
(lctl & PCIEM_LINK_CTL_ASPMC_L1) ? "En" : "Dis",
|
||||
sc->sc_ltr_enabled ? "En" : "Dis");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1790,6 +1790,7 @@ enum {
|
||||
/* Power - legacy power table command */
|
||||
IWM_POWER_TABLE_CMD = 0x77,
|
||||
IWM_PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
|
||||
IWM_LTR_CONFIG = 0xee,
|
||||
|
||||
/* Thermal Throttling*/
|
||||
IWM_REPLY_THERMAL_MNG_BACKOFF = 0x7e,
|
||||
@ -3522,6 +3523,57 @@ struct iwm_nonqos_seq_query_cmd {
|
||||
|
||||
/* Power Management Commands, Responses, Notifications */
|
||||
|
||||
/**
|
||||
* enum iwm_ltr_config_flags - masks for LTR config command flags
|
||||
* @IWM_LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status
|
||||
* @IWM_LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow
|
||||
* memory access
|
||||
* @IWM_LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR
|
||||
* reg change
|
||||
* @IWM_LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from
|
||||
* D0 to D3
|
||||
* @IWM_LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register
|
||||
* @IWM_LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register
|
||||
* @IWM_LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD
|
||||
*/
|
||||
enum iwm_ltr_config_flags {
|
||||
IWM_LTR_CFG_FLAG_FEATURE_ENABLE = (1 << 0),
|
||||
IWM_LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = (1 << 1),
|
||||
IWM_LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = (1 << 2),
|
||||
IWM_LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = (1 << 3),
|
||||
IWM_LTR_CFG_FLAG_SW_SET_SHORT = (1 << 4),
|
||||
IWM_LTR_CFG_FLAG_SW_SET_LONG = (1 << 5),
|
||||
IWM_LTR_CFG_FLAG_DENIE_C10_ON_PD = (1 << 6),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_ltr_config_cmd_v1 - configures the LTR
|
||||
* @flags: See %enum iwm_ltr_config_flags
|
||||
*/
|
||||
struct iwm_ltr_config_cmd_v1 {
|
||||
uint32_t flags;
|
||||
uint32_t static_long;
|
||||
uint32_t static_short;
|
||||
} __packed; /* LTR_CAPABLE_API_S_VER_1 */
|
||||
|
||||
#define IWM_LTR_VALID_STATES_NUM 4
|
||||
|
||||
/**
|
||||
* struct iwm_ltr_config_cmd - configures the LTR
|
||||
* @flags: See %enum iwm_ltr_config_flags
|
||||
* @static_long:
|
||||
* @static_short:
|
||||
* @ltr_cfg_values:
|
||||
* @ltr_short_idle_timeout:
|
||||
*/
|
||||
struct iwm_ltr_config_cmd {
|
||||
uint32_t flags;
|
||||
uint32_t static_long;
|
||||
uint32_t static_short;
|
||||
uint32_t ltr_cfg_values[IWM_LTR_VALID_STATES_NUM];
|
||||
uint32_t ltr_short_idle_timeout;
|
||||
} __packed; /* LTR_CAPABLE_API_S_VER_2 */
|
||||
|
||||
/* Radio LP RX Energy Threshold measured in dBm */
|
||||
#define IWM_POWER_LPRX_RSSI_THRESHOLD 75
|
||||
#define IWM_POWER_LPRX_RSSI_THRESHOLD_MAX 94
|
||||
|
@ -556,6 +556,8 @@ struct iwm_softc {
|
||||
|
||||
/* Indicate if device power save is allowed */
|
||||
boolean_t sc_ps_disabled;
|
||||
|
||||
int sc_ltr_enabled;
|
||||
};
|
||||
|
||||
#define IWM_LOCK_INIT(_sc) \
|
||||
|
Loading…
Reference in New Issue
Block a user