/*
 * Copyright (c) 2014 Redpine Signals Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/firmware.h>
#include <net/bluetooth/bluetooth.h>
#include "rsi_mgmt.h"
#include "rsi_hal.h"
#include "rsi_sdio.h"
#include "rsi_common.h"

/* FLASH Firmware */
static struct ta_metadata metadata_flash_content[] = {
	{"flash_content", 0x00010000},
	{"rsi/rs9113_wlan_qspi.rps", 0x00010000},
	{"rsi/rs9113_wlan_bt_dual_mode.rps", 0x00010000},
	{"flash_content", 0x00010000},
	{"rsi/rs9113_ap_bt_dual_mode.rps", 0x00010000},

};

static struct ta_metadata metadata[] = {{"pmemdata_dummy", 0x00000000},
	{"rsi/rs9116_wlan.rps", 0x00000000},
	{"rsi/rs9116_wlan_bt_classic.rps", 0x00000000},
	{"rsi/pmemdata_dummy", 0x00000000},
	{"rsi/rs9116_wlan_bt_classic.rps", 0x00000000}
};

int rsi_send_pkt_to_bus(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	int status;

	if (common->coex_mode > 1)
		mutex_lock(&common->tx_bus_mutex);

	status = adapter->host_intf_ops->write_pkt(common->priv,
						   skb->data, skb->len);

	if (common->coex_mode > 1)
		mutex_unlock(&common->tx_bus_mutex);

	return status;
}

int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	struct ieee80211_hdr *wh = NULL;
	struct ieee80211_tx_info *info;
	struct ieee80211_conf *conf = &adapter->hw->conf;
	struct ieee80211_vif *vif;
	struct rsi_mgmt_desc *mgmt_desc;
	struct skb_info *tx_params;
	struct rsi_xtended_desc *xtend_desc = NULL;
	u8 header_size;
	u32 dword_align_bytes = 0;

	if (skb->len > MAX_MGMT_PKT_SIZE) {
		rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
		return -EINVAL;
	}

	info = IEEE80211_SKB_CB(skb);
	tx_params = (struct skb_info *)info->driver_data;
	vif = tx_params->vif;

	/* Update header size */
	header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
	if (header_size > skb_headroom(skb)) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to add extended descriptor\n",
			__func__);
		return -ENOSPC;
	}
	skb_push(skb, header_size);
	dword_align_bytes = ((unsigned long)skb->data & 0x3f);
	if (dword_align_bytes > skb_headroom(skb)) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to add dword align\n", __func__);
		return -ENOSPC;
	}
	skb_push(skb, dword_align_bytes);
	header_size += dword_align_bytes;

	tx_params->internal_hdr_size = header_size;
	memset(&skb->data[0], 0, header_size);
	wh = (struct ieee80211_hdr *)&skb->data[header_size];

	mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
	xtend_desc = (struct rsi_xtended_desc *)&skb->data[FRAME_DESC_SZ];

	rsi_set_len_qno(&mgmt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
			RSI_WIFI_MGMT_Q);
	mgmt_desc->frame_type = TX_DOT11_MGMT;
	mgmt_desc->header_len = MIN_802_11_HDR_LEN;
	mgmt_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;

	if (ieee80211_is_probe_req(wh->frame_control))
		mgmt_desc->frame_info = cpu_to_le16(RSI_INSERT_SEQ_IN_FW);
	mgmt_desc->frame_info |= cpu_to_le16(RATE_INFO_ENABLE);
	if (is_broadcast_ether_addr(wh->addr1))
		mgmt_desc->frame_info |= cpu_to_le16(RSI_BROADCAST_PKT);

	mgmt_desc->seq_ctrl =
		cpu_to_le16(IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl)));
	if ((common->band == NL80211_BAND_2GHZ) && !common->p2p_enabled)
		mgmt_desc->rate_info = cpu_to_le16(RSI_RATE_1);
	else
		mgmt_desc->rate_info = cpu_to_le16(RSI_RATE_6);

	if (conf_is_ht40(conf))
		mgmt_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);

	if (ieee80211_is_probe_resp(wh->frame_control)) {
		mgmt_desc->misc_flags |= (RSI_ADD_DELTA_TSF_VAP_ID |
					  RSI_FETCH_RETRY_CNT_FRM_HST);
#define PROBE_RESP_RETRY_CNT	3
		xtend_desc->retry_cnt = PROBE_RESP_RETRY_CNT;
	}

	if (((vif->type == NL80211_IFTYPE_AP) ||
	     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
	    (ieee80211_is_action(wh->frame_control))) {
		struct rsi_sta *rsta = rsi_find_sta(common, wh->addr1);

		if (rsta)
			mgmt_desc->sta_id = tx_params->sta_id;
		else
			return -EINVAL;
	}
	mgmt_desc->rate_info |=
		cpu_to_le16((tx_params->vap_id << RSI_DESC_VAP_ID_OFST) &
			    RSI_DESC_VAP_ID_MASK);

	return 0;
}

/* This function prepares descriptor for given data packet */
int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	struct ieee80211_vif *vif;
	struct ieee80211_hdr *wh = NULL;
	struct ieee80211_tx_info *info;
	struct skb_info *tx_params;
	struct rsi_data_desc *data_desc;
	struct rsi_xtended_desc *xtend_desc;
	u8 ieee80211_size = MIN_802_11_HDR_LEN;
	u8 header_size;
	u8 vap_id = 0;
	u8 dword_align_bytes;
	bool tx_eapol;
	u16 seq_num;

	info = IEEE80211_SKB_CB(skb);
	vif = info->control.vif;
	tx_params = (struct skb_info *)info->driver_data;

	tx_eapol = IEEE80211_SKB_CB(skb)->control.flags &
		   IEEE80211_TX_CTRL_PORT_CTRL_PROTO;

	header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
	if (header_size > skb_headroom(skb)) {
		rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
		return -ENOSPC;
	}
	skb_push(skb, header_size);
	dword_align_bytes = ((unsigned long)skb->data & 0x3f);
	if (header_size > skb_headroom(skb)) {
		rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
		return -ENOSPC;
	}
	skb_push(skb, dword_align_bytes);
	header_size += dword_align_bytes;

	tx_params->internal_hdr_size = header_size;
	data_desc = (struct rsi_data_desc *)skb->data;
	memset(data_desc, 0, header_size);

	xtend_desc = (struct rsi_xtended_desc *)&skb->data[FRAME_DESC_SZ];
	wh = (struct ieee80211_hdr *)&skb->data[header_size];
	seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl));

	data_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;

	if (ieee80211_is_data_qos(wh->frame_control)) {
		ieee80211_size += 2;
		data_desc->mac_flags |= cpu_to_le16(RSI_QOS_ENABLE);
	}

	if (((vif->type == NL80211_IFTYPE_STATION) ||
	     (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
	    (adapter->ps_state == PS_ENABLED))
		wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE);

	if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
	    tx_params->have_key) {
		if (rsi_is_cipher_wep(common))
			ieee80211_size += 4;
		else
			ieee80211_size += 8;
		data_desc->mac_flags |= cpu_to_le16(RSI_ENCRYPT_PKT);
	}
	rsi_set_len_qno(&data_desc->len_qno, (skb->len - FRAME_DESC_SZ),
			RSI_WIFI_DATA_Q);
	data_desc->header_len = ieee80211_size;

	if (common->rate_config[common->band].fixed_enabled) {
		/* Send fixed rate */
		u16 fixed_rate = common->rate_config[common->band].fixed_hw_rate;

		data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
		data_desc->rate_info = cpu_to_le16(fixed_rate);

		if (conf_is_ht40(&common->priv->hw->conf))
			data_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);

		if (common->vif_info[0].sgi && (fixed_rate & 0x100)) {
		       /* Only MCS rates */
			data_desc->rate_info |=
				cpu_to_le16(ENABLE_SHORTGI_RATE);
		}
	}

	if (tx_eapol) {
		rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");

		data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
		if (common->band == NL80211_BAND_5GHZ)
			data_desc->rate_info = cpu_to_le16(RSI_RATE_6);
		else
			data_desc->rate_info = cpu_to_le16(RSI_RATE_1);
		data_desc->mac_flags |= cpu_to_le16(RSI_REKEY_PURPOSE);
		data_desc->misc_flags |= RSI_FETCH_RETRY_CNT_FRM_HST;
#define EAPOL_RETRY_CNT 15
		xtend_desc->retry_cnt = EAPOL_RETRY_CNT;

		if (common->eapol4_confirm)
			skb->priority = VO_Q;
		else
			rsi_set_len_qno(&data_desc->len_qno,
					(skb->len - FRAME_DESC_SZ),
					RSI_WIFI_MGMT_Q);
		if (((skb->len - header_size) == EAPOL4_PACKET_LEN) ||
		    ((skb->len - header_size) == EAPOL4_PACKET_LEN - 2)) {
			data_desc->misc_flags |=
				RSI_DESC_REQUIRE_CFM_TO_HOST;
			xtend_desc->confirm_frame_type = EAPOL4_CONFIRM;
		}
	}

	data_desc->mac_flags |= cpu_to_le16(seq_num & 0xfff);
	data_desc->qid_tid = ((skb->priority & 0xf) |
			      ((tx_params->tid & 0xf) << 4));
	data_desc->sta_id = tx_params->sta_id;

	if ((is_broadcast_ether_addr(wh->addr1)) ||
	    (is_multicast_ether_addr(wh->addr1))) {
		data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
		data_desc->frame_info |= cpu_to_le16(RSI_BROADCAST_PKT);
		data_desc->sta_id = vap_id;

		if ((vif->type == NL80211_IFTYPE_AP) ||
		    (vif->type == NL80211_IFTYPE_P2P_GO)) {
			if (common->band == NL80211_BAND_5GHZ)
				data_desc->rate_info = cpu_to_le16(RSI_RATE_6);
			else
				data_desc->rate_info = cpu_to_le16(RSI_RATE_1);
		}
	}
	if (((vif->type == NL80211_IFTYPE_AP) ||
	     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
	    (ieee80211_has_moredata(wh->frame_control)))
		data_desc->frame_info |= cpu_to_le16(MORE_DATA_PRESENT);

	data_desc->rate_info |=
		cpu_to_le16((tx_params->vap_id << RSI_DESC_VAP_ID_OFST) &
			    RSI_DESC_VAP_ID_MASK);

	return 0;
}

/* This function sends received data packet from driver to device */
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	struct ieee80211_vif *vif;
	struct ieee80211_tx_info *info;
	struct ieee80211_bss_conf *bss;
	int status = -EINVAL;

	if (!skb)
		return 0;
	if (common->iface_down)
		goto err;

	info = IEEE80211_SKB_CB(skb);
	if (!info->control.vif)
		goto err;
	vif = info->control.vif;
	bss = &vif->bss_conf;

	if (((vif->type == NL80211_IFTYPE_STATION) ||
	     (vif->type == NL80211_IFTYPE_P2P_CLIENT)) &&
	    (!bss->assoc))
		goto err;

	status = rsi_send_pkt_to_bus(common, skb);
	if (status)
		rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n", __func__);

err:
	++common->tx_stats.total_tx_pkt_freed[skb->priority];
	rsi_indicate_tx_status(adapter, skb, status);
	return status;
}

/**
 * rsi_send_mgmt_pkt() - This functions sends the received management packet
 *			 from driver to device.
 * @common: Pointer to the driver private structure.
 * @skb: Pointer to the socket buffer structure.
 *
 * Return: status: 0 on success, -1 on failure.
 */
int rsi_send_mgmt_pkt(struct rsi_common *common,
		      struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	struct ieee80211_bss_conf *bss;
	struct ieee80211_hdr *wh;
	struct ieee80211_tx_info *info;
	struct skb_info *tx_params;
	struct rsi_mgmt_desc *mgmt_desc;
	struct rsi_xtended_desc *xtend_desc;
	int status = -E2BIG;
	u8 header_size;

	info = IEEE80211_SKB_CB(skb);
	tx_params = (struct skb_info *)info->driver_data;
	header_size = tx_params->internal_hdr_size;

	if (tx_params->flags & INTERNAL_MGMT_PKT) {
		status = adapter->host_intf_ops->write_pkt(common->priv,
							   (u8 *)skb->data,
							   skb->len);
		if (status) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to write the packet\n", __func__);
		}
		dev_kfree_skb(skb);
		return status;
	}

	bss = &info->control.vif->bss_conf;
	wh = (struct ieee80211_hdr *)&skb->data[header_size];
	mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
	xtend_desc = (struct rsi_xtended_desc *)&skb->data[FRAME_DESC_SZ];

	/* Indicate to firmware to give cfm for probe */
	if (ieee80211_is_probe_req(wh->frame_control) && !bss->assoc) {
		rsi_dbg(INFO_ZONE,
			"%s: blocking mgmt queue\n", __func__);
		mgmt_desc->misc_flags = RSI_DESC_REQUIRE_CFM_TO_HOST;
		xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM;
		common->mgmt_q_block = true;
		rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
	}

	status = rsi_send_pkt_to_bus(common, skb);
	if (status)
		rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__);

	rsi_indicate_tx_status(common->priv, skb, status);
	return status;
}

int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
{
	int status = -EINVAL;
	u8 header_size = 0;
	struct rsi_bt_desc *bt_desc;
	u8 queueno = ((skb->data[1] >> 4) & 0xf);

	if (queueno == RSI_BT_MGMT_Q) {
		status = rsi_send_pkt_to_bus(common, skb);
		if (status)
			rsi_dbg(ERR_ZONE, "%s: Failed to write bt mgmt pkt\n",
				__func__);
		goto out;
	}
	header_size = FRAME_DESC_SZ;
	if (header_size > skb_headroom(skb)) {
		rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
		status = -ENOSPC;
		goto out;
	}
	skb_push(skb, header_size);
	memset(skb->data, 0, header_size);
	bt_desc = (struct rsi_bt_desc *)skb->data;

	rsi_set_len_qno(&bt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
			RSI_BT_DATA_Q);
	bt_desc->bt_pkt_type = cpu_to_le16(bt_cb(skb)->pkt_type);

	status = rsi_send_pkt_to_bus(common, skb);
	if (status)
		rsi_dbg(ERR_ZONE, "%s: Failed to write bt pkt\n", __func__);

out:
	dev_kfree_skb(skb);
	return status;
}

int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = (struct rsi_hw *)common->priv;
	struct rsi_data_desc *bcn_frm;
	struct ieee80211_hw *hw = common->priv->hw;
	struct ieee80211_conf *conf = &hw->conf;
	struct ieee80211_vif *vif;
	struct sk_buff *mac_bcn;
	u8 vap_id = 0, i;
	u16 tim_offset = 0;

	for (i = 0; i < RSI_MAX_VIFS; i++) {
		vif = adapter->vifs[i];
		if (!vif)
			continue;
		if ((vif->type == NL80211_IFTYPE_AP) ||
		    (vif->type == NL80211_IFTYPE_P2P_GO))
			break;
	}
	if (!vif)
		return -EINVAL;
	mac_bcn = ieee80211_beacon_get_tim(adapter->hw,
					   vif,
					   &tim_offset, NULL);
	if (!mac_bcn) {
		rsi_dbg(ERR_ZONE, "Failed to get beacon from mac80211\n");
		return -EINVAL;
	}

	common->beacon_cnt++;
	bcn_frm = (struct rsi_data_desc *)skb->data;
	rsi_set_len_qno(&bcn_frm->len_qno, mac_bcn->len, RSI_WIFI_DATA_Q);
	bcn_frm->header_len = MIN_802_11_HDR_LEN;
	bcn_frm->frame_info = cpu_to_le16(RSI_DATA_DESC_MAC_BBP_INFO |
					  RSI_DATA_DESC_NO_ACK_IND |
					  RSI_DATA_DESC_BEACON_FRAME |
					  RSI_DATA_DESC_INSERT_TSF |
					  RSI_DATA_DESC_INSERT_SEQ_NO |
					  RATE_INFO_ENABLE);
	bcn_frm->rate_info = cpu_to_le16(vap_id << 14);
	bcn_frm->qid_tid = BEACON_HW_Q;

	if (conf_is_ht40_plus(conf)) {
		bcn_frm->bbp_info = cpu_to_le16(LOWER_20_ENABLE);
		bcn_frm->bbp_info |= cpu_to_le16(LOWER_20_ENABLE >> 12);
	} else if (conf_is_ht40_minus(conf)) {
		bcn_frm->bbp_info = cpu_to_le16(UPPER_20_ENABLE);
		bcn_frm->bbp_info |= cpu_to_le16(UPPER_20_ENABLE >> 12);
	}

	if (common->band == NL80211_BAND_2GHZ)
		bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_1);
	else
		bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_6);

	if (mac_bcn->data[tim_offset + 2] == 0)
		bcn_frm->frame_info |= cpu_to_le16(RSI_DATA_DESC_DTIM_BEACON);

	memcpy(&skb->data[FRAME_DESC_SZ], mac_bcn->data, mac_bcn->len);
	skb_put(skb, mac_bcn->len + FRAME_DESC_SZ);

	dev_kfree_skb(mac_bcn);

	return 0;
}

static void bl_cmd_timeout(struct timer_list *t)
{
	struct rsi_hw *adapter = from_timer(adapter, t, bl_cmd_timer);

	adapter->blcmd_timer_expired = true;
	del_timer(&adapter->bl_cmd_timer);
}

static int bl_start_cmd_timer(struct rsi_hw *adapter, u32 timeout)
{
	timer_setup(&adapter->bl_cmd_timer, bl_cmd_timeout, 0);
	adapter->bl_cmd_timer.expires = (msecs_to_jiffies(timeout) + jiffies);

	adapter->blcmd_timer_expired = false;
	add_timer(&adapter->bl_cmd_timer);

	return 0;
}

static int bl_stop_cmd_timer(struct rsi_hw *adapter)
{
	adapter->blcmd_timer_expired = false;
	if (timer_pending(&adapter->bl_cmd_timer))
		del_timer(&adapter->bl_cmd_timer);

	return 0;
}

static int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp,
			u16 *cmd_resp)
{
	struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
	u32 regin_val = 0, regout_val = 0;
	u32 regin_input = 0;
	u8 output = 0;
	int status;

	regin_input = (REGIN_INPUT | adapter->priv->coex_mode);

	while (!adapter->blcmd_timer_expired) {
		regin_val = 0;
		status = hif_ops->master_reg_read(adapter, SWBL_REGIN,
						  &regin_val, 2);
		if (status < 0) {
			rsi_dbg(ERR_ZONE,
				"%s: Command %0x REGIN reading failed..\n",
				__func__, cmd);
			return status;
		}
		mdelay(1);
		if ((regin_val >> 12) != REGIN_VALID)
			break;
	}
	if (adapter->blcmd_timer_expired) {
		rsi_dbg(ERR_ZONE,
			"%s: Command %0x REGIN reading timed out..\n",
			__func__, cmd);
		return -ETIMEDOUT;
	}

	rsi_dbg(INFO_ZONE,
		"Issuing write to Regin val:%0x sending cmd:%0x\n",
		regin_val, (cmd | regin_input << 8));
	status = hif_ops->master_reg_write(adapter, SWBL_REGIN,
					   (cmd | regin_input << 8), 2);
	if (status < 0)
		return status;
	mdelay(1);

	if (cmd == LOAD_HOSTED_FW || cmd == JUMP_TO_ZERO_PC) {
		/* JUMP_TO_ZERO_PC doesn't expect
		 * any response. So return from here
		 */
		return 0;
	}

	while (!adapter->blcmd_timer_expired) {
		regout_val = 0;
		status = hif_ops->master_reg_read(adapter, SWBL_REGOUT,
					     &regout_val, 2);
		if (status < 0) {
			rsi_dbg(ERR_ZONE,
				"%s: Command %0x REGOUT reading failed..\n",
				__func__, cmd);
			return status;
		}
		mdelay(1);
		if ((regout_val >> 8) == REGOUT_VALID)
			break;
	}
	if (adapter->blcmd_timer_expired) {
		rsi_dbg(ERR_ZONE,
			"%s: Command %0x REGOUT reading timed out..\n",
			__func__, cmd);
		return status;
	}

	*cmd_resp = ((u16 *)&regout_val)[0] & 0xffff;

	output = ((u8 *)&regout_val)[0] & 0xff;

	status = hif_ops->master_reg_write(adapter, SWBL_REGOUT,
					   (cmd | REGOUT_INVALID << 8), 2);
	if (status < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Command %0x REGOUT writing failed..\n",
			__func__, cmd);
		return status;
	}
	mdelay(1);

	if (output != exp_resp) {
		rsi_dbg(ERR_ZONE,
			"%s: Recvd resp %x for cmd %0x\n",
			__func__, output, cmd);
		return -EINVAL;
	}
	rsi_dbg(INFO_ZONE,
		"%s: Recvd Expected resp %x for cmd %0x\n",
		__func__, output, cmd);

	return 0;
}

static int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str)
{
	u16 regout_val = 0;
	u32 timeout;
	int status;

	if ((cmd == EOF_REACHED) || (cmd == PING_VALID) || (cmd == PONG_VALID))
		timeout = BL_BURN_TIMEOUT;
	else
		timeout = BL_CMD_TIMEOUT;

	bl_start_cmd_timer(adapter, timeout);
	status = bl_write_cmd(adapter, cmd, exp_resp, &regout_val);
	if (status < 0) {
		bl_stop_cmd_timer(adapter);
		rsi_dbg(ERR_ZONE,
			"%s: Command %s (%0x) writing failed..\n",
			__func__, str, cmd);
		return status;
	}
	bl_stop_cmd_timer(adapter);
	return 0;
}

#define CHECK_SUM_OFFSET 20
#define LEN_OFFSET 8
#define ADDR_OFFSET 16
static int bl_write_header(struct rsi_hw *adapter, u8 *flash_content,
			   u32 content_size)
{
	struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
	struct bl_header *bl_hdr;
	u32 write_addr, write_len;
	int status;

	bl_hdr = kzalloc(sizeof(*bl_hdr), GFP_KERNEL);
	if (!bl_hdr)
		return -ENOMEM;

	bl_hdr->flags = 0;
	bl_hdr->image_no = cpu_to_le32(adapter->priv->coex_mode);
	bl_hdr->check_sum =
		cpu_to_le32(*(u32 *)&flash_content[CHECK_SUM_OFFSET]);
	bl_hdr->flash_start_address =
		cpu_to_le32(*(u32 *)&flash_content[ADDR_OFFSET]);
	bl_hdr->flash_len = cpu_to_le32(*(u32 *)&flash_content[LEN_OFFSET]);
	write_len = sizeof(struct bl_header);

	if (adapter->rsi_host_intf == RSI_HOST_INTF_USB) {
		write_addr = PING_BUFFER_ADDRESS;
		status = hif_ops->write_reg_multiple(adapter, write_addr,
						 (u8 *)bl_hdr, write_len);
		if (status < 0) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to load Version/CRC structure\n",
				__func__);
			goto fail;
		}
	} else {
		write_addr = PING_BUFFER_ADDRESS >> 16;
		status = hif_ops->master_access_msword(adapter, write_addr);
		if (status < 0) {
			rsi_dbg(ERR_ZONE,
				"%s: Unable to set ms word to common reg\n",
				__func__);
			goto fail;
		}
		write_addr = RSI_SD_REQUEST_MASTER |
			     (PING_BUFFER_ADDRESS & 0xFFFF);
		status = hif_ops->write_reg_multiple(adapter, write_addr,
						 (u8 *)bl_hdr, write_len);
		if (status < 0) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to load Version/CRC structure\n",
				__func__);
			goto fail;
		}
	}
	status = 0;
fail:
	kfree(bl_hdr);
	return status;
}

static u32 read_flash_capacity(struct rsi_hw *adapter)
{
	u32 flash_sz = 0;

	if ((adapter->host_intf_ops->master_reg_read(adapter, FLASH_SIZE_ADDR,
						     &flash_sz, 2)) < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Flash size reading failed..\n",
			__func__);
		return 0;
	}
	rsi_dbg(INIT_ZONE, "Flash capacity: %d KiloBytes\n", flash_sz);

	return (flash_sz * 1024); /* Return size in kbytes */
}

static int ping_pong_write(struct rsi_hw *adapter, u8 cmd, u8 *addr, u32 size)
{
	struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
	u32 block_size = adapter->block_size;
	u32 cmd_addr;
	u16 cmd_resp, cmd_req;
	u8 *str;
	int status;

	if (cmd == PING_WRITE) {
		cmd_addr = PING_BUFFER_ADDRESS;
		cmd_resp = PONG_AVAIL;
		cmd_req = PING_VALID;
		str = "PING_VALID";
	} else {
		cmd_addr = PONG_BUFFER_ADDRESS;
		cmd_resp = PING_AVAIL;
		cmd_req = PONG_VALID;
		str = "PONG_VALID";
	}

	status = hif_ops->load_data_master_write(adapter, cmd_addr, size,
					    block_size, addr);
	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Unable to write blk at addr %0x\n",
			__func__, *addr);
		return status;
	}

	status = bl_cmd(adapter, cmd_req, cmd_resp, str);
	if (status)
		return status;

	return 0;
}

static int auto_fw_upgrade(struct rsi_hw *adapter, u8 *flash_content,
			   u32 content_size)
{
	u8 cmd;
	u32 temp_content_size, num_flash, index;
	u32 flash_start_address;
	int status;

	if (content_size > MAX_FLASH_FILE_SIZE) {
		rsi_dbg(ERR_ZONE,
			"%s: Flash Content size is more than 400K %u\n",
			__func__, MAX_FLASH_FILE_SIZE);
		return -EINVAL;
	}

	flash_start_address = *(u32 *)&flash_content[FLASH_START_ADDRESS];
	rsi_dbg(INFO_ZONE, "flash start address: %08x\n", flash_start_address);

	if (flash_start_address < FW_IMAGE_MIN_ADDRESS) {
		rsi_dbg(ERR_ZONE,
			"%s: Fw image Flash Start Address is less than 64K\n",
			__func__);
		return -EINVAL;
	}

	if (flash_start_address % FLASH_SECTOR_SIZE) {
		rsi_dbg(ERR_ZONE,
			"%s: Flash Start Address is not multiple of 4K\n",
			__func__);
		return -EINVAL;
	}

	if ((flash_start_address + content_size) > adapter->flash_capacity) {
		rsi_dbg(ERR_ZONE,
			"%s: Flash Content will cross max flash size\n",
			__func__);
		return -EINVAL;
	}

	temp_content_size  = content_size;
	num_flash = content_size / FLASH_WRITE_CHUNK_SIZE;

	rsi_dbg(INFO_ZONE, "content_size: %d, num_flash: %d\n",
		content_size, num_flash);

	for (index = 0; index <= num_flash; index++) {
		rsi_dbg(INFO_ZONE, "flash index: %d\n", index);
		if (index != num_flash) {
			content_size = FLASH_WRITE_CHUNK_SIZE;
			rsi_dbg(INFO_ZONE, "QSPI content_size:%d\n",
				content_size);
		} else {
			content_size =
				temp_content_size % FLASH_WRITE_CHUNK_SIZE;
			rsi_dbg(INFO_ZONE,
				"Writing last sector content_size:%d\n",
				content_size);
			if (!content_size) {
				rsi_dbg(INFO_ZONE, "instruction size zero\n");
				break;
			}
		}

		if (index % 2)
			cmd = PING_WRITE;
		else
			cmd = PONG_WRITE;

		status = ping_pong_write(adapter, cmd, flash_content,
					 content_size);
		if (status) {
			rsi_dbg(ERR_ZONE, "%s: Unable to load %d block\n",
				__func__, index);
			return status;
		}

		rsi_dbg(INFO_ZONE,
			"%s: Successfully loaded %d instructions\n",
			__func__, index);
		flash_content += content_size;
	}

	status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL,
			"EOF_REACHED");
	if (status)
		return status;

	rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
	return 0;
}

static int rsi_hal_prepare_fwload(struct rsi_hw *adapter)
{
	struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
	u32 regout_val = 0;
	int status;

	bl_start_cmd_timer(adapter, BL_CMD_TIMEOUT);

	while (!adapter->blcmd_timer_expired) {
		status = hif_ops->master_reg_read(adapter, SWBL_REGOUT,
						  &regout_val,
						  RSI_COMMON_REG_SIZE);
		if (status < 0) {
			bl_stop_cmd_timer(adapter);
			rsi_dbg(ERR_ZONE,
				"%s: REGOUT read failed\n", __func__);
			return status;
		}
		mdelay(1);
		if ((regout_val >> 8) == REGOUT_VALID)
			break;
	}
	if (adapter->blcmd_timer_expired) {
		rsi_dbg(ERR_ZONE, "%s: REGOUT read timedout\n", __func__);
		rsi_dbg(ERR_ZONE,
			"%s: Soft boot loader not present\n", __func__);
		return -ETIMEDOUT;
	}
	bl_stop_cmd_timer(adapter);

	rsi_dbg(INFO_ZONE, "Received Board Version Number: %x\n",
		(regout_val & 0xff));

	status = hif_ops->master_reg_write(adapter, SWBL_REGOUT,
					   (REGOUT_INVALID |
					    REGOUT_INVALID << 8),
					   RSI_COMMON_REG_SIZE);
	if (status < 0)
		rsi_dbg(ERR_ZONE, "%s: REGOUT writing failed..\n", __func__);
	else
		rsi_dbg(INFO_ZONE,
			"===> Device is ready to load firmware <===\n");

	return status;
}

static int rsi_load_9113_firmware(struct rsi_hw *adapter)
{
	struct rsi_common *common = adapter->priv;
	const struct firmware *fw_entry = NULL;
	u32 content_size;
	u16 tmp_regout_val = 0;
	struct ta_metadata *metadata_p;
	int status;

	status = bl_cmd(adapter, CONFIG_AUTO_READ_MODE, CMD_PASS,
			"AUTO_READ_CMD");
	if (status < 0)
		return status;

	adapter->flash_capacity = read_flash_capacity(adapter);
	if (adapter->flash_capacity <= 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Unable to read flash size from EEPROM\n",
			__func__);
		return -EINVAL;
	}

	metadata_p = &metadata_flash_content[adapter->priv->coex_mode];

	rsi_dbg(INIT_ZONE, "%s: Loading file %s\n", __func__, metadata_p->name);
	adapter->fw_file_name = metadata_p->name;

	status = request_firmware(&fw_entry, metadata_p->name, adapter->device);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "%s: Failed to open file %s\n",
			__func__, metadata_p->name);
		return status;
	}
	content_size = fw_entry->size;
	rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", content_size);

	/* Get the firmware version */
	common->lmac_ver.ver.info.fw_ver[0] =
		fw_entry->data[LMAC_VER_OFFSET_9113] & 0xFF;
	common->lmac_ver.ver.info.fw_ver[1] =
		fw_entry->data[LMAC_VER_OFFSET_9113 + 1] & 0xFF;
	common->lmac_ver.major =
		fw_entry->data[LMAC_VER_OFFSET_9113 + 2] & 0xFF;
	common->lmac_ver.release_num =
		fw_entry->data[LMAC_VER_OFFSET_9113 + 3] & 0xFF;
	common->lmac_ver.minor =
		fw_entry->data[LMAC_VER_OFFSET_9113 + 4] & 0xFF;
	common->lmac_ver.patch_num = 0;
	rsi_print_version(common);

	status = bl_write_header(adapter, (u8 *)fw_entry->data, content_size);
	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: RPS Image header loading failed\n",
			__func__);
		goto fail;
	}

	bl_start_cmd_timer(adapter, BL_CMD_TIMEOUT);
	status = bl_write_cmd(adapter, CHECK_CRC, CMD_PASS, &tmp_regout_val);
	if (status) {
		bl_stop_cmd_timer(adapter);
		rsi_dbg(ERR_ZONE,
			"%s: CHECK_CRC Command writing failed..\n",
			__func__);
		if ((tmp_regout_val & 0xff) == CMD_FAIL) {
			rsi_dbg(ERR_ZONE,
				"CRC Fail.. Proceeding to Upgrade mode\n");
			goto fw_upgrade;
		}
	}
	bl_stop_cmd_timer(adapter);

	status = bl_cmd(adapter, POLLING_MODE, CMD_PASS, "POLLING_MODE");
	if (status)
		goto fail;

load_image_cmd:
	status = bl_cmd(adapter, LOAD_HOSTED_FW, LOADING_INITIATED,
			"LOAD_HOSTED_FW");
	if (status)
		goto fail;
	rsi_dbg(INFO_ZONE, "Load Image command passed..\n");
	goto success;

fw_upgrade:
	status = bl_cmd(adapter, BURN_HOSTED_FW, SEND_RPS_FILE, "FW_UPGRADE");
	if (status)
		goto fail;

	rsi_dbg(INFO_ZONE, "Burn Command Pass.. Upgrading the firmware\n");

	status = auto_fw_upgrade(adapter, (u8 *)fw_entry->data, content_size);
	if (status == 0) {
		rsi_dbg(ERR_ZONE, "Firmware upgradation Done\n");
		goto load_image_cmd;
	}
	rsi_dbg(ERR_ZONE, "Firmware upgrade failed\n");

	status = bl_cmd(adapter, CONFIG_AUTO_READ_MODE, CMD_PASS,
			"AUTO_READ_MODE");
	if (status)
		goto fail;

success:
	rsi_dbg(ERR_ZONE, "***** Firmware Loading successful *****\n");
	release_firmware(fw_entry);
	return 0;

fail:
	rsi_dbg(ERR_ZONE, "##### Firmware loading failed #####\n");
	release_firmware(fw_entry);
	return status;
}

static int rsi_load_9116_firmware(struct rsi_hw *adapter)
{
	struct rsi_common *common = adapter->priv;
	struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
	const struct firmware *fw_entry;
	struct ta_metadata *metadata_p;
	u8 *ta_firmware, *fw_p;
	struct bootload_ds bootload_ds;
	u32 instructions_sz, base_address;
	u16 block_size = adapter->block_size;
	u32 dest, len;
	int status, cnt;

	rsi_dbg(INIT_ZONE, "***** Load 9116 TA Instructions *****\n");

	if (adapter->rsi_host_intf == RSI_HOST_INTF_USB) {
		status = bl_cmd(adapter, POLLING_MODE, CMD_PASS,
				"POLLING_MODE");
		if (status < 0)
			return status;
	}

	status = hif_ops->master_reg_write(adapter, MEM_ACCESS_CTRL_FROM_HOST,
					   RAM_384K_ACCESS_FROM_TA,
					   RSI_9116_REG_SIZE);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "%s: Unable to access full RAM memory\n",
			__func__);
		return status;
	}

	metadata_p = &metadata[adapter->priv->coex_mode];
	rsi_dbg(INIT_ZONE, "%s: loading file %s\n", __func__, metadata_p->name);
	status = request_firmware(&fw_entry, metadata_p->name, adapter->device);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "%s: Failed to open file %s\n",
			__func__, metadata_p->name);
		return status;
	}

	ta_firmware = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
	if (!ta_firmware) {
		status = -ENOMEM;
		goto fail_release_fw;
	}
	fw_p = ta_firmware;
	instructions_sz = fw_entry->size;
	rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", instructions_sz);

	common->lmac_ver.major = ta_firmware[LMAC_VER_OFFSET_9116];
	common->lmac_ver.minor = ta_firmware[LMAC_VER_OFFSET_9116 + 1];
	common->lmac_ver.release_num = ta_firmware[LMAC_VER_OFFSET_9116 + 2];
	common->lmac_ver.patch_num = ta_firmware[LMAC_VER_OFFSET_9116 + 3];
	common->lmac_ver.ver.info.fw_ver[0] =
		ta_firmware[LMAC_VER_OFFSET_9116 + 4];

	if (instructions_sz % FW_ALIGN_SIZE)
		instructions_sz +=
			(FW_ALIGN_SIZE - (instructions_sz % FW_ALIGN_SIZE));
	rsi_dbg(INFO_ZONE, "instructions_sz : %d\n", instructions_sz);

	if (*(u16 *)fw_p == RSI_9116_FW_MAGIC_WORD) {
		memcpy(&bootload_ds, fw_p, sizeof(struct bootload_ds));
		fw_p += le16_to_cpu(bootload_ds.offset);
		rsi_dbg(INFO_ZONE, "FW start = %x\n", *(u32 *)fw_p);

		cnt = 0;
		do {
			rsi_dbg(ERR_ZONE, "%s: Loading chunk %d\n",
				__func__, cnt);

			dest = le32_to_cpu(bootload_ds.bl_entry[cnt].dst_addr);
			len = le32_to_cpu(bootload_ds.bl_entry[cnt].control) &
			      RSI_BL_CTRL_LEN_MASK;
			rsi_dbg(INFO_ZONE, "length %d destination %x\n",
				len, dest);

			status = hif_ops->load_data_master_write(adapter, dest,
								 len,
								 block_size,
								 fw_p);
			if (status < 0) {
				rsi_dbg(ERR_ZONE,
					"Failed to load chunk %d\n", cnt);
				break;
			}
			fw_p += len;
			if (le32_to_cpu(bootload_ds.bl_entry[cnt].control) &
			    RSI_BL_CTRL_LAST_ENTRY)
				break;
			cnt++;
		} while (1);
	} else {
		base_address = metadata_p->address;
		status = hif_ops->load_data_master_write(adapter,
							 base_address,
							 instructions_sz,
							 block_size,
							 ta_firmware);
	}
	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: Unable to load %s blk\n",
			__func__, metadata_p->name);
		goto fail_free_fw;
	}

	rsi_dbg(INIT_ZONE, "%s: Successfully loaded %s instructions\n",
		__func__, metadata_p->name);

	if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO) {
		if (hif_ops->ta_reset(adapter))
			rsi_dbg(ERR_ZONE, "Unable to put ta in reset\n");
	} else {
		if (bl_cmd(adapter, JUMP_TO_ZERO_PC,
			   CMD_PASS, "JUMP_TO_ZERO") < 0)
			rsi_dbg(INFO_ZONE, "Jump to zero command failed\n");
		else
			rsi_dbg(INFO_ZONE, "Jump to zero command successful\n");
	}

fail_free_fw:
	kfree(ta_firmware);
fail_release_fw:
	release_firmware(fw_entry);

	return status;
}

int rsi_hal_device_init(struct rsi_hw *adapter)
{
	struct rsi_common *common = adapter->priv;
	int status;

	switch (adapter->device_model) {
	case RSI_DEV_9113:
		status = rsi_hal_prepare_fwload(adapter);
		if (status < 0)
			return status;
		if (rsi_load_9113_firmware(adapter)) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to load TA instructions\n",
				__func__);
			return -EINVAL;
		}
		break;
	case RSI_DEV_9116:
		status = rsi_hal_prepare_fwload(adapter);
		if (status < 0)
			return status;
		if (rsi_load_9116_firmware(adapter)) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to load firmware to 9116 device\n",
				__func__);
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	common->fsm_state = FSM_CARD_NOT_READY;

	return 0;
}
EXPORT_SYMBOL_GPL(rsi_hal_device_init);

