示例#1
0
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;
}
示例#2
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;
}
示例#3
0
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;
}
示例#4
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;
}