static int iwm_init_calib(struct iwm_priv *iwm, unsigned long cfg_bitmap, unsigned long expected_bitmap, u8 rx_iq_cmd) { if (test_bit(rx_iq_cmd, &cfg_bitmap)) { iwm_store_rxiq_calib_result(iwm); set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map); } iwm_send_prio_table(iwm); iwm_send_init_calib_cfg(iwm, cfg_bitmap); while (iwm->calib_done_map != expected_bitmap) { if (iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION, IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT)) { IWM_DBG_FW(iwm, DBG, "Initial calibration timeout\n"); return -ETIMEDOUT; } IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: " "0x%lx, expected calibrations: 0x%lx\n", iwm->calib_done_map, expected_bitmap); } return 0; }
int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags) { int ret; /* Use UMAC default values */ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_POWER_INDEX, iwm->conf.power_index); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX, CFG_FRAG_THRESHOLD, iwm->conf.frag_threshold); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_RTS_THRESHOLD, iwm->conf.rts_threshold); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_CTS_TO_SELF, iwm->conf.cts_to_self); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_COEX_MODE, iwm->conf.coexist_mode); if (ret < 0) return ret; /* ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_ASSOCIATION_TIMEOUT, iwm->conf.assoc_timeout); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_ROAM_TIMEOUT, iwm->conf.roam_timeout); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_WIRELESS_MODE, WIRELESS_MODE_11A | WIRELESS_MODE_11G); if (ret < 0) return ret; */ ret = iwm_umac_set_config_var(iwm, CFG_NET_ADDR, iwm_to_ndev(iwm)->dev_addr, ETH_ALEN); if (ret < 0) return ret; /* UMAC PM static configurations */ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_LEGACY_RX_TIMEOUT, 0x12C); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_LEGACY_TX_TIMEOUT, 0x15E); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_CTRL_FLAGS, 0x30001); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_KEEP_ALIVE_IN_BEACONS, 0x80); if (ret < 0) return ret; /* reset UMAC */ ret = iwm_send_umac_reset(iwm, reset_flags, 1); if (ret < 0) return ret; ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Wait for UMAC RESET timeout\n"); return ret; } return ret; }
static int iwm_eeprom_read(struct iwm_priv *iwm, u8 eeprom_id) { int ret; u32 entry_size, chunk_size, data_offset = 0, addr_offset = 0; u32 addr; struct iwm_udma_wifi_cmd udma_cmd; struct iwm_umac_cmd umac_cmd; struct iwm_umac_cmd_eeprom_proxy eeprom_cmd; if (eeprom_id > (IWM_EEPROM_LAST - 1)) return -EINVAL; entry_size = eeprom_map[eeprom_id].length; if (eeprom_id >= IWM_EEPROM_INDIRECT_DATA) { /* indirect data */ u32 off_id = eeprom_id - IWM_EEPROM_INDIRECT_DATA + IWM_EEPROM_INDIRECT_OFFSET; eeprom_map[eeprom_id].offset = *(u16 *)(iwm->eeprom + eeprom_map[off_id].offset) << 1; } addr = eeprom_map[eeprom_id].offset; udma_cmd.eop = 1; udma_cmd.credit_group = 0x4; udma_cmd.ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD; udma_cmd.lmac_offset = 0; umac_cmd.id = UMAC_CMD_OPCODE_EEPROM_PROXY; umac_cmd.resp = 1; while (entry_size > 0) { chunk_size = min_t(u32, entry_size, IWM_MAX_EEPROM_DATA_LEN); eeprom_cmd.hdr.type = cpu_to_le32(IWM_UMAC_CMD_EEPROM_TYPE_READ); eeprom_cmd.hdr.offset = cpu_to_le32(addr + addr_offset); eeprom_cmd.hdr.len = cpu_to_le32(chunk_size); ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &eeprom_cmd, sizeof(struct iwm_umac_cmd_eeprom_proxy)); if (ret < 0) { IWM_ERR(iwm, "Couldn't read eeprom\n"); return ret; } ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_EEPROM_PROXY, IWM_SRC_UMAC, 2*HZ); if (ret < 0) { IWM_ERR(iwm, "Did not get any eeprom answer\n"); return ret; } data_offset += chunk_size; addr_offset += chunk_size; entry_size -= chunk_size; } return 0; }
int iwm_load_fw(struct iwm_priv *iwm) { unsigned long init_calib_map, periodic_calib_map; unsigned long expected_calib_map; int ret; ret = iwm_load_umac(iwm); if (ret < 0) { IWM_ERR(iwm, "UMAC loading failed\n"); return ret; } ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_ALIVE, IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Handle UMAC_ALIVE failed: %d\n", ret); return ret; } ret = iwm_load_lmac(iwm, iwm->bus_ops->calib_lmac_name); if (ret) { IWM_ERR(iwm, "Calibration LMAC loading failed\n"); return ret; } ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE, IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Handle INIT_COMPLETE failed for calibration " "LMAC: %d\n", ret); return ret; } ret = iwm_eeprom_init(iwm); if (ret < 0) { IWM_ERR(iwm, "Couldn't init eeprom array\n"); return ret; } init_calib_map = iwm->conf.calib_map & IWM_CALIB_MAP_INIT_MSK; expected_calib_map = iwm->conf.expected_calib_map & IWM_CALIB_MAP_INIT_MSK; periodic_calib_map = IWM_CALIB_MAP_PER_LMAC(iwm->conf.calib_map); ret = iwm_init_calib(iwm, init_calib_map, expected_calib_map, CALIB_CFG_RX_IQ_IDX); if (ret < 0) { ret = iwm_init_calib(iwm, expected_calib_map, expected_calib_map, PHY_CALIBRATE_RX_IQ_CMD); if (ret < 0) { IWM_ERR(iwm, "Calibration result timeout\n"); goto out; } } ret = iwm_notif_handle(iwm, CALIBRATION_COMPLETE_NOTIFICATION, IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Wait for CALIBRATION_COMPLETE timeout\n"); goto out; } IWM_INFO(iwm, "LMAC calibration done: 0x%lx\n", iwm->calib_done_map); iwm_send_umac_reset(iwm, cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_RESET), 1); ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Wait for UMAC RESET timeout\n"); goto out; } ret = iwm_load_lmac(iwm, iwm->bus_ops->lmac_name); if (ret) { IWM_ERR(iwm, "LMAC loading failed\n"); goto out; } ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE, IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Handle INIT_COMPLETE failed for LMAC: %d\n", ret); goto out; } iwm_send_prio_table(iwm); iwm_send_calib_results(iwm); iwm_send_periodic_calib_cfg(iwm, periodic_calib_map); iwm_send_ct_kill_cfg(iwm, iwm->conf.ct_kill_entry, iwm->conf.ct_kill_exit); return 0; out: iwm_eeprom_exit(iwm); return ret; }
int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags) { int ret; /* */ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_POWER_INDEX, iwm->conf.power_index); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX, CFG_FRAG_THRESHOLD, iwm->conf.frag_threshold); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_RTS_THRESHOLD, iwm->conf.rts_threshold); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_CTS_TO_SELF, iwm->conf.cts_to_self); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_WIRELESS_MODE, iwm->conf.wireless_mode); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_COEX_MODE, modparam_wiwi); if (ret < 0) return ret; /* */ ret = iwm_umac_set_config_var(iwm, CFG_NET_ADDR, iwm_to_ndev(iwm)->dev_addr, ETH_ALEN); if (ret < 0) return ret; /* */ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_LEGACY_RX_TIMEOUT, 0x12C); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_LEGACY_TX_TIMEOUT, 0x15E); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_CTRL_FLAGS, 0x1); if (ret < 0) return ret; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_PM_KEEP_ALIVE_IN_BEACONS, 0x80); if (ret < 0) return ret; /* */ ret = iwm_send_umac_reset(iwm, reset_flags, 1); if (ret < 0) return ret; ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT); if (ret) { IWM_ERR(iwm, "Wait for UMAC RESET timeout\n"); return ret; } return ret; }