/*
 * Intel Wireless Multicomm 3200 WiFi driver
 *
 * Copyright (C) 2009 Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * Intel Corporation <ilw@linux.intel.com>
 * Samuel Ortiz <samuel.ortiz@intel.com>
 * Zhu Yi <yi.zhu@intel.com>
 *
 */

#include <linux/kernel.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <linux/ieee80211.h>
#include <linux/sched.h>

#include "iwm.h"
#include "bus.h"
#include "hal.h"
#include "umac.h"
#include "commands.h"
#include "debug.h"

static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm,
				     u8 lmac_cmd_id,
				     const void *lmac_payload,
				     u16 lmac_payload_size,
				     u8 resp)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_LMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_lmac_cmd lmac_cmd;

	lmac_cmd.id = lmac_cmd_id;

	umac_cmd.id = UMAC_CMD_OPCODE_WIFI_PASS_THROUGH;
	umac_cmd.resp = resp;

	return iwm_hal_send_host_cmd(iwm, &udma_cmd, &umac_cmd, &lmac_cmd,
				     lmac_payload, lmac_payload_size);
}

int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
			 bool resp)
{
	struct iwm_umac_wifi_if *hdr = (struct iwm_umac_wifi_if *)payload;
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	int ret;
	u8 oid = hdr->oid;

	if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
		IWM_ERR(iwm, "Interface is not ready yet");
		return -EAGAIN;
	}

	umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
	umac_cmd.resp = resp;

	ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
				    payload, payload_size);

	if (resp) {
		ret = wait_event_interruptible_timeout(iwm->wifi_ntfy_queue,
				   test_and_clear_bit(oid, &iwm->wifi_ntfy[0]),
				   3 * HZ);

		return ret ? 0 : -EBUSY;
	}

	return ret;
}

static int modparam_wiwi = COEX_MODE_CM;
module_param_named(wiwi, modparam_wiwi, int, 0644);
MODULE_PARM_DESC(wiwi, "Wifi-WiMAX coexistence: 1=SA, 2=XOR, 3=CM (default)");

static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] =
{
	{4, 3, 0, COEX_UNASSOC_IDLE_FLAGS},
	{4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
	{4, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
	{4, 3, 0, COEX_CALIBRATION_FLAGS},
	{4, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
	{4, 3, 0, COEX_CONNECTION_ESTAB_FLAGS},
	{4, 3, 0, COEX_ASSOCIATED_IDLE_FLAGS},
	{4, 3, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
	{4, 3, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
	{4, 3, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
	{6, 3, 0, COEX_XOR_RF_ON_FLAGS},
	{4, 3, 0, COEX_RF_OFF_FLAGS},
	{6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
	{4, 3, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
	{4, 3, 0, COEX_RSRVD1_FLAGS},
	{4, 3, 0, COEX_RSRVD2_FLAGS}
};

static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] =
{
	{1, 1, 0, COEX_UNASSOC_IDLE_FLAGS},
	{4, 4, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
	{3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
	{6, 6, 0, COEX_CALIBRATION_FLAGS},
	{3, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
	{6, 5, 0, COEX_CONNECTION_ESTAB_FLAGS},
	{4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS},
	{4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
	{4, 4, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
	{4, 4, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
	{1, 1, 0, COEX_RF_ON_FLAGS},
	{1, 1, 0, COEX_RF_OFF_FLAGS},
	{7, 7, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
	{5, 4, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
	{1, 1, 0, COEX_RSRVD1_FLAGS},
	{1, 1, 0, COEX_RSRVD2_FLAGS}
};

int iwm_send_prio_table(struct iwm_priv *iwm)
{
	struct iwm_coex_prio_table_cmd coex_table_cmd;
	u32 coex_enabled, mode_enabled;

	memset(&coex_table_cmd, 0, sizeof(struct iwm_coex_prio_table_cmd));

	coex_table_cmd.flags = COEX_FLAGS_STA_TABLE_VALID_MSK;

	switch (modparam_wiwi) {
	case COEX_MODE_XOR:
	case COEX_MODE_CM:
		coex_enabled = 1;
		break;
	default:
		coex_enabled = 0;
		break;
	}

	switch (iwm->conf.mode) {
	case UMAC_MODE_BSS:
	case UMAC_MODE_IBSS:
		mode_enabled = 1;
		break;
	default:
		mode_enabled = 0;
		break;
	}

	if (coex_enabled && mode_enabled) {
		coex_table_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK |
					COEX_FLAGS_ASSOC_WAKEUP_UMASK_MSK |
					COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK;

		switch (modparam_wiwi) {
		case COEX_MODE_XOR:
			memcpy(coex_table_cmd.sta_prio, iwm_sta_xor_prio_tbl,
			       sizeof(iwm_sta_xor_prio_tbl));
			break;
		case COEX_MODE_CM:
			memcpy(coex_table_cmd.sta_prio, iwm_sta_cm_prio_tbl,
			       sizeof(iwm_sta_cm_prio_tbl));
			break;
		default:
			IWM_ERR(iwm, "Invalid coex_mode 0x%x\n",
				modparam_wiwi);
			break;
		}
	} else
		IWM_WARN(iwm, "coexistense disabled\n");

	return iwm_send_lmac_ptrough_cmd(iwm, COEX_PRIORITY_TABLE_CMD,
				&coex_table_cmd,
				sizeof(struct iwm_coex_prio_table_cmd), 0);
}

int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
{
	struct iwm_lmac_cal_cfg_cmd cal_cfg_cmd;

	memset(&cal_cfg_cmd, 0, sizeof(struct iwm_lmac_cal_cfg_cmd));

	cal_cfg_cmd.ucode_cfg.init.enable = cpu_to_le32(calib_requested);
	cal_cfg_cmd.ucode_cfg.init.start = cpu_to_le32(calib_requested);
	cal_cfg_cmd.ucode_cfg.init.send_res = cpu_to_le32(calib_requested);
	cal_cfg_cmd.ucode_cfg.flags =
		cpu_to_le32(CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK);

	return iwm_send_lmac_ptrough_cmd(iwm, CALIBRATION_CFG_CMD, &cal_cfg_cmd,
				sizeof(struct iwm_lmac_cal_cfg_cmd), 1);
}

int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
{
	struct iwm_lmac_cal_cfg_cmd cal_cfg_cmd;

	memset(&cal_cfg_cmd, 0, sizeof(struct iwm_lmac_cal_cfg_cmd));

	cal_cfg_cmd.ucode_cfg.periodic.enable = cpu_to_le32(calib_requested);
	cal_cfg_cmd.ucode_cfg.periodic.start = cpu_to_le32(calib_requested);

	return iwm_send_lmac_ptrough_cmd(iwm, CALIBRATION_CFG_CMD, &cal_cfg_cmd,
				sizeof(struct iwm_lmac_cal_cfg_cmd), 0);
}

int iwm_store_rxiq_calib_result(struct iwm_priv *iwm)
{
	struct iwm_calib_rxiq *rxiq;
	u8 *eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);
	int grplen = sizeof(struct iwm_calib_rxiq_group);

	rxiq = kzalloc(sizeof(struct iwm_calib_rxiq), GFP_KERNEL);
	if (!rxiq) {
		IWM_ERR(iwm, "Couldn't alloc memory for RX IQ\n");
		return -ENOMEM;
	}

	eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);
	if (IS_ERR(eeprom_rxiq)) {
		IWM_ERR(iwm, "Couldn't access EEPROM RX IQ entry\n");
		kfree(rxiq);
		return PTR_ERR(eeprom_rxiq);
	}

	iwm->calib_res[SHILOH_PHY_CALIBRATE_RX_IQ_CMD].buf = (u8 *)rxiq;
	iwm->calib_res[SHILOH_PHY_CALIBRATE_RX_IQ_CMD].size = sizeof(*rxiq);

	rxiq->hdr.opcode = SHILOH_PHY_CALIBRATE_RX_IQ_CMD;
	rxiq->hdr.first_grp = 0;
	rxiq->hdr.grp_num = 1;
	rxiq->hdr.all_data_valid = 1;

	memcpy(&rxiq->group[0], eeprom_rxiq, 4 * grplen);
	memcpy(&rxiq->group[4], eeprom_rxiq + 6 * grplen, grplen);

	return 0;
}

int iwm_send_calib_results(struct iwm_priv *iwm)
{
	int i, ret = 0;

	for (i = PHY_CALIBRATE_OPCODES_NUM; i < CALIBRATION_CMD_NUM; i++) {
		if (test_bit(i - PHY_CALIBRATE_OPCODES_NUM,
			     &iwm->calib_done_map)) {
			IWM_DBG_CMD(iwm, DBG,
				    "Send calibration %d result\n", i);
			ret |= iwm_send_lmac_ptrough_cmd(iwm,
					REPLY_PHY_CALIBRATION_CMD,
					iwm->calib_res[i].buf,
					iwm->calib_res[i].size, 0);

			kfree(iwm->calib_res[i].buf);
			iwm->calib_res[i].buf = NULL;
			iwm->calib_res[i].size = 0;
		}
	}

	return ret;
}

int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit)
{
	struct iwm_ct_kill_cfg_cmd cmd;

	cmd.entry_threshold = entry;
	cmd.exit_threshold = exit;

	return iwm_send_lmac_ptrough_cmd(iwm, REPLY_CT_KILL_CONFIG_CMD, &cmd,
					 sizeof(struct iwm_ct_kill_cfg_cmd), 0);
}

int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_umac_cmd_reset reset;

	reset.flags = reset_flags;

	umac_cmd.id = UMAC_CMD_OPCODE_RESET;
	umac_cmd.resp = resp;

	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &reset,
				     sizeof(struct iwm_umac_cmd_reset));
}

int iwm_umac_set_config_fix(struct iwm_priv *iwm, u16 tbl, u16 key, u32 value)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_umac_cmd_set_param_fix param;

	if ((tbl != UMAC_PARAM_TBL_CFG_FIX) &&
	    (tbl != UMAC_PARAM_TBL_FA_CFG_FIX))
		return -EINVAL;

	umac_cmd.id = UMAC_CMD_OPCODE_SET_PARAM_FIX;
	umac_cmd.resp = 0;

	param.tbl = cpu_to_le16(tbl);
	param.key = cpu_to_le16(key);
	param.value = cpu_to_le32(value);

	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &param,
				     sizeof(struct iwm_umac_cmd_set_param_fix));
}

int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
			    void *payload, u16 payload_size)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_umac_cmd_set_param_var *param_hdr;
	u8 *param;
	int ret;

	param = kzalloc(payload_size +
			sizeof(struct iwm_umac_cmd_set_param_var), GFP_KERNEL);
	if (!param) {
		IWM_ERR(iwm, "Couldn't allocate param\n");
		return -ENOMEM;
	}

	param_hdr = (struct iwm_umac_cmd_set_param_var *)param;

	umac_cmd.id = UMAC_CMD_OPCODE_SET_PARAM_VAR;
	umac_cmd.resp = 0;

	param_hdr->tbl = cpu_to_le16(UMAC_PARAM_TBL_CFG_VAR);
	param_hdr->key = cpu_to_le16(key);
	param_hdr->len = cpu_to_le16(payload_size);
	memcpy(param + sizeof(struct iwm_umac_cmd_set_param_var),
	       payload, payload_size);

	ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, param,
				    sizeof(struct iwm_umac_cmd_set_param_var) +
				    payload_size);
	kfree(param);

	return ret;
}

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_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_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, 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;

	/* 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;
}

int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id)
{
	struct iwm_udma_wifi_cmd udma_cmd;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_tx_info *tx_info = skb_to_tx_info(skb);

	udma_cmd.eop = 1; /* always set eop for non-concatenated Tx */
	udma_cmd.credit_group = pool_id;
	udma_cmd.ra_tid = tx_info->sta << 4 | tx_info->tid;
	udma_cmd.lmac_offset = 0;

	umac_cmd.id = REPLY_TX;
	umac_cmd.color = tx_info->color;
	umac_cmd.resp = 0;

	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
				     skb->data, skb->len);
}

static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
			   u8 *response, u32 resp_size)
{
	struct iwm_udma_nonwifi_cmd target_cmd;
	struct iwm_nonwifi_cmd *cmd;
	u16 seq_num;
	int ret = 0;

	target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ;
	target_cmd.addr = address;
	target_cmd.op1_sz = cpu_to_le32(resp_size);
	target_cmd.op2 = 0;
	target_cmd.handle_by_hw = 0;
	target_cmd.resp = 1;
	target_cmd.eop = 1;

	ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
	if (ret < 0) {
		IWM_ERR(iwm, "Couldn't send READ command\n");
		return ret;
	}

	/* When succeding, the send_target routine returns the seq number */
	seq_num = ret;

	ret = wait_event_interruptible_timeout(iwm->nonwifi_queue,
		(cmd = iwm_get_pending_nonwifi_cmd(iwm, seq_num,
					  UMAC_HDI_OUT_OPCODE_READ)) != NULL,
					       2 * HZ);

	if (!ret) {
		IWM_ERR(iwm, "Didn't receive a target READ answer\n");
		return ret;
	}

	memcpy(response, cmd->buf.hdr + sizeof(struct iwm_udma_in_hdr),
	       resp_size);

	kfree(cmd);

	return 0;
}

int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
{
	int ret;
	u8 mac_align[ALIGN(ETH_ALEN, 8)];

	ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR),
			      mac_align, sizeof(mac_align));
	if (ret)
		return ret;

	if (is_valid_ether_addr(mac_align))
		memcpy(mac, mac_align, ETH_ALEN);
	else {
		IWM_ERR(iwm, "Invalid EEPROM MAC\n");
		memcpy(mac, iwm->conf.mac_addr, ETH_ALEN);
		get_random_bytes(&mac[3], 3);
	}

	return 0;
}

static int iwm_check_profile(struct iwm_priv *iwm)
{
	if (!iwm->umac_profile_active)
		return -EAGAIN;

	if (iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
	    iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104 &&
	    iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_TKIP &&
	    iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_CCMP) {
		IWM_ERR(iwm, "Wrong unicast cipher: 0x%x\n",
			iwm->umac_profile->sec.ucast_cipher);
		return -EAGAIN;
	}

	if (iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
	    iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_WEP_104 &&
	    iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_TKIP &&
	    iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_CCMP) {
		IWM_ERR(iwm, "Wrong multicast cipher: 0x%x\n",
			iwm->umac_profile->sec.mcast_cipher);
		return -EAGAIN;
	}

	if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
	     iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
	    (iwm->umac_profile->sec.ucast_cipher !=
	     iwm->umac_profile->sec.mcast_cipher)) {
		IWM_ERR(iwm, "Unicast and multicast ciphers differ for WEP\n");
	}

	return 0;
}

int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
{
	struct iwm_umac_tx_key_id tx_key_id;
	int ret;

	ret = iwm_check_profile(iwm);
	if (ret < 0)
		return ret;

	/* UMAC only allows to set default key for WEP and auth type is
	 * NOT 802.1X or RSNA. */
	if ((iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
	     iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104) ||
	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_8021X ||
	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_RSNA_PSK)
		return 0;

	tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
	tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
					     sizeof(struct iwm_umac_wifi_if));

	tx_key_id.key_idx = key_idx;

	return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
}

int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
{
	int ret = 0;
	u8 cmd[64], *sta_addr, *key_data, key_len;
	s8 key_idx;
	u16 cmd_size = 0;
	struct iwm_umac_key_hdr *key_hdr = &key->hdr;
	struct iwm_umac_key_wep40 *wep40 = (struct iwm_umac_key_wep40 *)cmd;
	struct iwm_umac_key_wep104 *wep104 = (struct iwm_umac_key_wep104 *)cmd;
	struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd;
	struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd;

	if (!remove) {
		ret = iwm_check_profile(iwm);
		if (ret < 0)
			return ret;
	}

	sta_addr = key->hdr.mac;
	key_data = key->key;
	key_len = key->key_len;
	key_idx = key->hdr.key_idx;

	if (!remove) {
		u8 auth_type = iwm->umac_profile->sec.auth_type;

		IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx);
		IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len);
		IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n",
		       key_hdr->mac, key_hdr->key_idx, key_hdr->multicast);

		IWM_DBG_WEXT(iwm, DBG, "profile: mcast:0x%x, ucast:0x%x\n",
			     iwm->umac_profile->sec.mcast_cipher,
			     iwm->umac_profile->sec.ucast_cipher);
		IWM_DBG_WEXT(iwm, DBG, "profile: auth_type:0x%x, flags:0x%x\n",
			     iwm->umac_profile->sec.auth_type,
			     iwm->umac_profile->sec.flags);

		switch (key->cipher) {
		case WLAN_CIPHER_SUITE_WEP40:
			wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY;
			wep40->hdr.buf_size =
				cpu_to_le16(sizeof(struct iwm_umac_key_wep40) -
					    sizeof(struct iwm_umac_wifi_if));

			memcpy(&wep40->key_hdr, key_hdr,
			       sizeof(struct iwm_umac_key_hdr));
			memcpy(wep40->key, key_data, key_len);
			wep40->static_key =
				!!((auth_type != UMAC_AUTH_TYPE_8021X) &&
				   (auth_type != UMAC_AUTH_TYPE_RSNA_PSK));

			cmd_size = sizeof(struct iwm_umac_key_wep40);
			break;

		case WLAN_CIPHER_SUITE_WEP104:
			wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY;
			wep104->hdr.buf_size =
				cpu_to_le16(sizeof(struct iwm_umac_key_wep104) -
					    sizeof(struct iwm_umac_wifi_if));

			memcpy(&wep104->key_hdr, key_hdr,
			       sizeof(struct iwm_umac_key_hdr));
			memcpy(wep104->key, key_data, key_len);
			wep104->static_key =
				!!((auth_type != UMAC_AUTH_TYPE_8021X) &&
				   (auth_type != UMAC_AUTH_TYPE_RSNA_PSK));

			cmd_size = sizeof(struct iwm_umac_key_wep104);
			break;

		case WLAN_CIPHER_SUITE_CCMP:
			key_hdr->key_idx++;
			ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY;
			ccmp->hdr.buf_size =
				cpu_to_le16(sizeof(struct iwm_umac_key_ccmp) -
					    sizeof(struct iwm_umac_wifi_if));

			memcpy(&ccmp->key_hdr, key_hdr,
			       sizeof(struct iwm_umac_key_hdr));

			memcpy(ccmp->key, key_data, key_len);

			if (key->seq_len)
				memcpy(ccmp->iv_count, key->seq, key->seq_len);

			cmd_size = sizeof(struct iwm_umac_key_ccmp);
			break;

		case WLAN_CIPHER_SUITE_TKIP:
			key_hdr->key_idx++;
			tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY;
			tkip->hdr.buf_size =
				cpu_to_le16(sizeof(struct iwm_umac_key_tkip) -
					    sizeof(struct iwm_umac_wifi_if));

			memcpy(&tkip->key_hdr, key_hdr,
			       sizeof(struct iwm_umac_key_hdr));

			memcpy(tkip->tkip_key, key_data, IWM_TKIP_KEY_SIZE);
			memcpy(tkip->mic_tx_key, key_data + IWM_TKIP_KEY_SIZE,
			       IWM_TKIP_MIC_SIZE);
			memcpy(tkip->mic_rx_key,
			       key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE,
			       IWM_TKIP_MIC_SIZE);

			if (key->seq_len)
				memcpy(ccmp->iv_count, key->seq, key->seq_len);

			cmd_size = sizeof(struct iwm_umac_key_tkip);
			break;

		default:
			return -ENOTSUPP;
		}

		if ((key->cipher == WLAN_CIPHER_SUITE_TKIP) ||
		    (key->cipher == WLAN_CIPHER_SUITE_CCMP))
			/*
			 * UGLY_UGLY_UGLY
			 * Copied HACK from the MWG driver.
			 * Without it, the key is set before the second
			 * EAPOL frame is sent, and the latter is thus
			 * encrypted.
			 */
			schedule_timeout_interruptible(usecs_to_jiffies(300));

		ret =  iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1);
	} else {
		struct iwm_umac_key_remove key_remove;

		IWM_DBG_WEXT(iwm, ERR, "Removing key_idx:%d\n", key_idx);

		key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY;
		key_remove.hdr.buf_size =
			cpu_to_le16(sizeof(struct iwm_umac_key_remove) -
				    sizeof(struct iwm_umac_wifi_if));
		memcpy(&key_remove.key_hdr, key_hdr,
		       sizeof(struct iwm_umac_key_hdr));

		ret =  iwm_send_wifi_if_cmd(iwm, &key_remove,
					    sizeof(struct iwm_umac_key_remove),
					    1);
		if (ret)
			return ret;

		iwm->keys[key_idx].key_len = 0;
	}

	return ret;
}


int iwm_send_mlme_profile(struct iwm_priv *iwm)
{
	int ret;
	struct iwm_umac_profile profile;

	memcpy(&profile, iwm->umac_profile, sizeof(profile));

	profile.hdr.oid = UMAC_WIFI_IF_CMD_SET_PROFILE;
	profile.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_profile) -
					   sizeof(struct iwm_umac_wifi_if));

	ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1);
	if (ret) {
		IWM_ERR(iwm, "Send profile command failed\n");
		return ret;
	}

	set_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
	return 0;
}

int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
{
	struct iwm_umac_invalidate_profile invalid;
	int ret;

	invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
	invalid.hdr.buf_size =
		cpu_to_le16(sizeof(struct iwm_umac_invalidate_profile) -
			    sizeof(struct iwm_umac_wifi_if));

	invalid.reason = WLAN_REASON_UNSPECIFIED;

	ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
	if (ret)
		return ret;

	ret = wait_event_interruptible_timeout(iwm->mlme_queue,
				(iwm->umac_profile_active == 0), 5 * HZ);

	return ret ? 0 : -EBUSY;
}

int iwm_tx_power_trigger(struct iwm_priv *iwm)
{
	struct iwm_umac_pwr_trigger pwr_trigger;

	pwr_trigger.hdr.oid = UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER;
	pwr_trigger.hdr.buf_size =
		cpu_to_le16(sizeof(struct iwm_umac_pwr_trigger) -
			    sizeof(struct iwm_umac_wifi_if));


	return iwm_send_wifi_if_cmd(iwm, &pwr_trigger, sizeof(pwr_trigger), 1);
}

int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_umac_cmd_stats_req stats_req;

	stats_req.flags = cpu_to_le32(flags);

	umac_cmd.id = UMAC_CMD_OPCODE_STATISTIC_REQUEST;
	umac_cmd.resp = 0;

	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &stats_req,
				     sizeof(struct iwm_umac_cmd_stats_req));
}

int iwm_send_umac_channel_list(struct iwm_priv *iwm)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_umac_cmd_get_channel_list *ch_list;
	int size = sizeof(struct iwm_umac_cmd_get_channel_list) +
		   sizeof(struct iwm_umac_channel_info) * 4;
	int ret;

	ch_list = kzalloc(size, GFP_KERNEL);
	if (!ch_list) {
		IWM_ERR(iwm, "Couldn't allocate channel list cmd\n");
		return -ENOMEM;
	}

	ch_list->ch[0].band = UMAC_BAND_2GHZ;
	ch_list->ch[0].type = UMAC_CHANNEL_WIDTH_20MHZ;
	ch_list->ch[0].flags = UMAC_CHANNEL_FLAG_VALID;

	ch_list->ch[1].band = UMAC_BAND_5GHZ;
	ch_list->ch[1].type = UMAC_CHANNEL_WIDTH_20MHZ;
	ch_list->ch[1].flags = UMAC_CHANNEL_FLAG_VALID;

	ch_list->ch[2].band = UMAC_BAND_2GHZ;
	ch_list->ch[2].type = UMAC_CHANNEL_WIDTH_20MHZ;
	ch_list->ch[2].flags = UMAC_CHANNEL_FLAG_VALID | UMAC_CHANNEL_FLAG_IBSS;

	ch_list->ch[3].band = UMAC_BAND_5GHZ;
	ch_list->ch[3].type = UMAC_CHANNEL_WIDTH_20MHZ;
	ch_list->ch[3].flags = UMAC_CHANNEL_FLAG_VALID | UMAC_CHANNEL_FLAG_IBSS;

	ch_list->count = cpu_to_le16(4);

	umac_cmd.id = UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST;
	umac_cmd.resp = 1;

	ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, ch_list, size);

	kfree(ch_list);

	return ret;
}

int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
		   int ssid_num)
{
	struct iwm_umac_cmd_scan_request req;
	int i, ret;

	memset(&req, 0, sizeof(struct iwm_umac_cmd_scan_request));

	req.hdr.oid = UMAC_WIFI_IF_CMD_SCAN_REQUEST;
	req.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_cmd_scan_request)
				       - sizeof(struct iwm_umac_wifi_if));
	req.type = UMAC_WIFI_IF_SCAN_TYPE_USER;
	req.timeout = 2;
	req.seq_num = iwm->scan_id;
	req.ssid_num = min(ssid_num, UMAC_WIFI_IF_PROBE_OPTION_MAX);

	for (i = 0; i < req.ssid_num; i++) {
		memcpy(req.ssids[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
		req.ssids[i].ssid_len = ssids[i].ssid_len;
	}

	ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0);
	if (ret) {
		IWM_ERR(iwm, "Couldn't send scan request\n");
		return ret;
	}

	iwm->scan_id = iwm->scan_id++ % IWM_SCAN_ID_MAX;

	return 0;
}

int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len)
{
	struct cfg80211_ssid one_ssid;

	if (test_and_set_bit(IWM_STATUS_SCANNING, &iwm->status))
		return 0;

	one_ssid.ssid_len = min(ssid_len, IEEE80211_MAX_SSID_LEN);
	memcpy(&one_ssid.ssid, ssid, one_ssid.ssid_len);

	return iwm_scan_ssids(iwm, &one_ssid, 1);
}

int iwm_target_reset(struct iwm_priv *iwm)
{
	struct iwm_udma_nonwifi_cmd target_cmd;

	target_cmd.opcode = UMAC_HDI_OUT_OPCODE_REBOOT;
	target_cmd.addr = 0;
	target_cmd.op1_sz = 0;
	target_cmd.op2 = 0;
	target_cmd.handle_by_hw = 0;
	target_cmd.resp = 0;
	target_cmd.eop = 1;

	return iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
}

int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm,
				 struct iwm_umac_notif_stop_resume_tx *ntf)
{
	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_umac_cmd_stop_resume_tx stp_res_cmd;
	struct iwm_sta_info *sta_info;
	u8 sta_id = STA_ID_N_COLOR_ID(ntf->sta_id);
	int i;

	sta_info = &iwm->sta_table[sta_id];
	if (!sta_info->valid) {
		IWM_ERR(iwm, "Invalid STA: %d\n", sta_id);
		return -EINVAL;
	}

	umac_cmd.id = UMAC_CMD_OPCODE_STOP_RESUME_STA_TX;
	umac_cmd.resp = 0;

	stp_res_cmd.flags = ntf->flags;
	stp_res_cmd.sta_id = ntf->sta_id;
	stp_res_cmd.stop_resume_tid_msk = ntf->stop_resume_tid_msk;
	for (i = 0; i < IWM_UMAC_TID_NR; i++)
		stp_res_cmd.last_seq_num[i] =
			sta_info->tid_info[i].last_seq_num;

	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &stp_res_cmd,
				 sizeof(struct iwm_umac_cmd_stop_resume_tx));

}

int iwm_send_pmkid_update(struct iwm_priv *iwm,
			  struct cfg80211_pmksa *pmksa, u32 command)
{
	struct iwm_umac_pmkid_update update;
	int ret;

	memset(&update, 0, sizeof(struct iwm_umac_pmkid_update));

	update.hdr.oid = UMAC_WIFI_IF_CMD_PMKID_UPDATE;
	update.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_pmkid_update) -
					  sizeof(struct iwm_umac_wifi_if));

	update.command = cpu_to_le32(command);
	if (pmksa->bssid)
		memcpy(&update.bssid, pmksa->bssid, ETH_ALEN);
	if (pmksa->pmkid)
		memcpy(&update.pmkid, pmksa->pmkid, WLAN_PMKID_LEN);

	ret = iwm_send_wifi_if_cmd(iwm, &update,
				   sizeof(struct iwm_umac_pmkid_update), 0);
	if (ret) {
		IWM_ERR(iwm, "PMKID update command failed\n");
		return ret;
	}

	return 0;
}
