/* * The device's EEPROM semaphore prevents conflicts between driver and uCode * when accessing the EEPROM; each access is a series of pulses to/from the * EEPROM chip, not a single event, so even reads could conflict if they * weren't arbitrated by the semaphore. */ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) { u16 count; int ret; for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { /* Request semaphore */ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); /* See if we got it */ ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, EEPROM_SEM_TIMEOUT); if (ret >= 0) { IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n", count+1); return ret; } } return ret; }
/* Note: returns standard 0/-ERROR code */ static int iwl_trans_prepare_card_hw(struct iwl_priv *priv) { int ret; IWL_DEBUG_INFO(priv, "iwl_trans_prepare_card_hw enter\n"); ret = iwl_set_hw_ready(priv); if (ret >= 0) return 0; /* If HW is not ready, prepare the conditions to check again */ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); if (ret < 0) return ret; /* HW should be ready by now, check again. */ ret = iwl_set_hw_ready(priv); if (ret >= 0) return 0; return ret; }
static int iwl_init_otp_access(struct iwl_trans *trans) { int ret; /* Enable 40MHz radio clock */ iwl_write32(trans, CSR_GP_CNTRL, iwl_read32(trans, CSR_GP_CNTRL) | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* wait for clock to be ready */ ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) { IWL_ERR(trans, "Time out access OTP\n"); } else { iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); udelay(5); iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); /* * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ if (trans->cfg->base_params->shadow_ram_support) iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); } return ret; }
/* Note: returns poll_bit return value, which is >= 0 if success */ static int iwl_set_hw_ready(struct iwl_priv *priv) { int ret; iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); /* See if we got it */ ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : ""); return ret; }
int iwl_grab_nic_access_silent(struct iwl_trans *trans) { int ret; lockdep_assert_held(&trans->reg_lock); /* this bit wakes up the NIC */ __iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* * These bits say the device is running, and should keep running for * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), * but they do not indicate that embedded SRAM is restored yet; * 3945 and 4965 have volatile SRAM, and must save/restore contents * to/from host DRAM when sleeping/waking for power-saving. * Each direction takes approximately 1/4 millisecond; with this * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a * series of register accesses are expected (e.g. reading Event Log), * to keep device from sleeping. * * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that * SRAM is okay/restored. We don't check that here because this call * is just for hardware register access; but GP1 MAC_SLEEP check is a * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). * * 5000 series and later (including 1000 series) have non-volatile SRAM, * and do not save/restore SRAM when power cycling. */ ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (ret < 0) { iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); return -EIO; } return 0; }
static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, __le16 *eeprom_data) { int ret = 0; u32 r; u32 otpgp; iwl_write32(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); ret = iwl_poll_bit(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); if (ret < 0) { IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); return ret; } r = iwl_read32(trans, CSR_EEPROM_REG); /* check for ECC errors: */ otpgp = iwl_read32(trans, CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { /* stop in this case */ /* set the uncorrectable OTP ECC bit for acknowledgement */ iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); return -EINVAL; } if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { /* continue in this case */ /* set the correctable OTP ECC bit for acknowledgement */ iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); } *eeprom_data = cpu_to_le16(r >> 16); return 0; }
/** * iwl_legacy_eeprom_init - read EEPROM contents * * Load the EEPROM contents from adapter into priv->eeprom * * NOTE: This routine uses the non-debug IO access functions. */ int iwl_legacy_eeprom_init(struct iwl_priv *priv) { __le16 *e; u32 gp = iwl_read32(priv, CSR_EEPROM_GP); int sz; int ret; u16 addr; /* allocate eeprom */ sz = priv->cfg->base_params->eeprom_size; IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); priv->eeprom = kzalloc(sz, GFP_KERNEL); if (!priv->eeprom) { ret = -ENOMEM; goto alloc_err; } e = (__le16 *)priv->eeprom; priv->cfg->ops->lib->apm_ops.init(priv); ret = iwl_legacy_eeprom_verify_signature(priv); if (ret < 0) { IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); ret = -ENOENT; goto err; } /* Make sure driver (instead of uCode) is allowed to read EEPROM */ ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); if (ret < 0) { IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); ret = -ENOENT; goto err; } /* eeprom is an array of 16bit values */ for (addr = 0; addr < sz; addr += sizeof(u16)) { u32 r; _iwl_legacy_write32(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); ret = iwl_poll_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); if (ret < 0) { IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); goto done; } r = _iwl_legacy_read_direct32(priv, CSR_EEPROM_REG); e[addr / 2] = cpu_to_le16(r >> 16); } IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", "EEPROM", iwl_legacy_eeprom_query16(priv, EEPROM_VERSION)); ret = 0; done: priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); err: if (ret) iwl_legacy_eeprom_free(priv); /* Reset chip to save power until we load uCode during "up". */ iwl_legacy_apm_stop(priv); alloc_err: return ret; }
/** * iwl_read_eeprom - read EEPROM contents * * Load the EEPROM contents from adapter and return it * and its size. * * NOTE: This routine uses the non-debug IO access functions. */ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) { __le16 *e; u32 gp = iwl_read32(trans, CSR_EEPROM_GP); int sz; int ret; u16 addr; u16 validblockaddr = 0; u16 cache_addr = 0; int nvm_is_otp; if (!eeprom || !eeprom_size) return -EINVAL; nvm_is_otp = iwl_nvm_is_otp(trans); if (nvm_is_otp < 0) return nvm_is_otp; sz = trans->cfg->base_params->eeprom_size; IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); e = kmalloc(sz, GFP_KERNEL); if (!e) return -ENOMEM; ret = iwl_eeprom_verify_signature(trans, nvm_is_otp); if (ret < 0) { IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); goto err_free; } /* Make sure driver (instead of uCode) is allowed to read EEPROM */ ret = iwl_eeprom_acquire_semaphore(trans); if (ret < 0) { IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); goto err_free; } if (nvm_is_otp) { ret = iwl_init_otp_access(trans); if (ret) { IWL_ERR(trans, "Failed to initialize OTP access.\n"); goto err_unlock; } iwl_write32(trans, CSR_EEPROM_GP, iwl_read32(trans, CSR_EEPROM_GP) & ~CSR_EEPROM_GP_IF_OWNER_MSK); iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ if (!trans->cfg->base_params->shadow_ram_support) { ret = iwl_find_otp_image(trans, &validblockaddr); if (ret) goto err_unlock; } for (addr = validblockaddr; addr < validblockaddr + sz; addr += sizeof(u16)) { __le16 eeprom_data; ret = iwl_read_otp_word(trans, addr, &eeprom_data); if (ret) goto err_unlock; e[cache_addr / 2] = eeprom_data; cache_addr += sizeof(u16); } } else { /* eeprom is an array of 16bit values */ for (addr = 0; addr < sz; addr += sizeof(u16)) { u32 r; iwl_write32(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); ret = iwl_poll_bit(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); if (ret < 0) { IWL_ERR(trans, "Time out reading EEPROM[%d]\n", addr); goto err_unlock; } r = iwl_read32(trans, CSR_EEPROM_REG); e[addr / 2] = cpu_to_le16(r >> 16); } } IWL_DEBUG_EEPROM(trans->dev, "NVM Type: %s\n", nvm_is_otp ? "OTP" : "EEPROM"); iwl_eeprom_release_semaphore(trans); *eeprom_size = sz; *eeprom = (u8 *)e; return 0; err_unlock: iwl_eeprom_release_semaphore(trans); err_free: kfree(e); return ret; }