/*
 * Marvell Wireless LAN device driver: HW/FW Initialization
 *
 * Copyright (C) 2011, Marvell International Ltd.
 *
 * This software file (the "File") is distributed by Marvell International
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 * (the "License").  You may use, redistribute and/or modify this File in
 * accordance with the terms and conditions of the License, a copy of which
 * is available by writing to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 * this warranty disclaimer.
 */

#include "decl.h"
#include "ioctl.h"
#include "util.h"
#include "fw.h"
#include "main.h"
#include "wmm.h"
#include "11n.h"

/*
 * This function adds a BSS priority table to the table list.
 *
 * The function allocates a new BSS priority table node and adds it to
 * the end of BSS priority table list, kept in driver memory.
 */
static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
{
	struct mwifiex_adapter *adapter = priv->adapter;
	struct mwifiex_bss_prio_node *bss_prio;
	unsigned long flags;

	bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
	if (!bss_prio) {
		dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
						__func__);
		return -ENOMEM;
	}

	bss_prio->priv = priv;
	INIT_LIST_HEAD(&bss_prio->list);
	if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
		adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
			bss_prio;

	spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
			.bss_prio_lock, flags);
	list_add_tail(&bss_prio->list,
			&adapter->bss_prio_tbl[priv->bss_priority]
			.bss_prio_head);
	spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
			.bss_prio_lock, flags);

	return 0;
}

/*
 * This function initializes the private structure and sets default
 * values to the members.
 *
 * Additionally, it also initializes all the locks and sets up all the
 * lists.
 */
static int mwifiex_init_priv(struct mwifiex_private *priv)
{
	u32 i;

	priv->media_connected = false;
	memset(priv->curr_addr, 0xff, ETH_ALEN);

	priv->pkt_tx_ctrl = 0;
	priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
	priv->data_rate = 0;	/* Initially indicate the rate as auto */
	priv->is_data_rate_auto = true;
	priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
	priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;

	priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
	priv->sec_info.encryption_mode = 0;
	for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
		memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key));
	priv->wep_key_curr_index = 0;
	priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
				HostCmd_ACT_MAC_ETHERNETII_ENABLE;

	priv->beacon_period = 100; /* beacon interval */ ;
	priv->attempted_bss_desc = NULL;
	memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
	priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;

	memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
	memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
	memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
	priv->assoc_rsp_size = 0;
	priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
	priv->atim_window = 0;
	priv->adhoc_state = ADHOC_IDLE;
	priv->tx_power_level = 0;
	priv->max_tx_power_level = 0;
	priv->min_tx_power_level = 0;
	priv->tx_rate = 0;
	priv->rxpd_htinfo = 0;
	priv->rxpd_rate = 0;
	priv->rate_bitmap = 0;
	priv->data_rssi_last = 0;
	priv->data_rssi_avg = 0;
	priv->data_nf_avg = 0;
	priv->data_nf_last = 0;
	priv->bcn_rssi_last = 0;
	priv->bcn_rssi_avg = 0;
	priv->bcn_nf_avg = 0;
	priv->bcn_nf_last = 0;
	memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
	memset(&priv->aes_key, 0, sizeof(priv->aes_key));
	priv->wpa_ie_len = 0;
	priv->wpa_is_gtk_set = false;

	memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf));
	priv->assoc_tlv_buf_len = 0;
	memset(&priv->wps, 0, sizeof(priv->wps));
	memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
	priv->gen_ie_buf_len = 0;
	memset(priv->vs_ie, 0, sizeof(priv->vs_ie));

	priv->wmm_required = true;
	priv->wmm_enabled = false;
	priv->wmm_qosinfo = 0;
	priv->curr_bcn_buf = NULL;
	priv->curr_bcn_size = 0;

	priv->scan_block = false;

	return mwifiex_add_bss_prio_tbl(priv);
}

/*
 * This function allocates buffers for members of the adapter
 * structure.
 *
 * The memory allocated includes scan table, command buffers, and
 * sleep confirm command buffer. In addition, the queues are
 * also initialized.
 */
static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
{
	int ret;

	/* Allocate command buffer */
	ret = mwifiex_alloc_cmd_buffer(adapter);
	if (ret) {
		dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n",
		       __func__);
		return -1;
	}

	adapter->sleep_cfm =
		dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
				+ INTF_HEADER_LEN);

	if (!adapter->sleep_cfm) {
		dev_err(adapter->dev, "%s: failed to alloc sleep cfm"
			" cmd buffer\n", __func__);
		return -1;
	}
	skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);

	return 0;
}

/*
 * This function initializes the adapter structure and sets default
 * values to the members of adapter.
 *
 * This also initializes the WMM related parameters in the driver private
 * structures.
 */
static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
{
	struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL;

	skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm));

	adapter->cmd_sent = false;

	if (adapter->iface_type == MWIFIEX_PCIE)
		adapter->data_sent = false;
	else
		adapter->data_sent = true;

	adapter->cmd_resp_received = false;
	adapter->event_received = false;
	adapter->data_received = false;

	adapter->surprise_removed = false;

	adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;

	adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
	adapter->ps_state = PS_STATE_AWAKE;
	adapter->need_to_wakeup = false;

	adapter->scan_mode = HostCmd_BSS_MODE_ANY;
	adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
	adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
	adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;

	adapter->scan_probes = 1;

	adapter->multiple_dtim = 1;

	adapter->local_listen_interval = 0;	/* default value in firmware
						   will be used */

	adapter->is_deep_sleep = false;

	adapter->delay_null_pkt = false;
	adapter->delay_to_ps = 1000;
	adapter->enhanced_ps_mode = PS_MODE_AUTO;

	adapter->gen_null_pkt = false;	/* Disable NULL Pkg generation by
					   default */
	adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by
					   default */
	adapter->pm_wakeup_card_req = false;

	adapter->pm_wakeup_fw_try = false;

	adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
	adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
	adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;

	adapter->is_hs_configured = false;
	adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF);
	adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF;
	adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF;
	adapter->hs_activated = false;

	memset(adapter->event_body, 0, sizeof(adapter->event_body));
	adapter->hw_dot_11n_dev_cap = 0;
	adapter->hw_dev_mcs_support = 0;
	adapter->sec_chan_offset = 0;
	adapter->adhoc_11n_enabled = false;

	mwifiex_wmm_init(adapter);

	if (adapter->sleep_cfm) {
		sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
						adapter->sleep_cfm->data;
		memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
		sleep_cfm_buf->command =
				cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
		sleep_cfm_buf->size =
				cpu_to_le16(adapter->sleep_cfm->len);
		sleep_cfm_buf->result = 0;
		sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
		sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
	}
	memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
	memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
	adapter->tx_lock_flag = false;
	adapter->null_pkt_interval = 0;
	adapter->fw_bands = 0;
	adapter->config_bands = 0;
	adapter->adhoc_start_band = 0;
	adapter->scan_channels = NULL;
	adapter->fw_release_number = 0;
	adapter->fw_cap_info = 0;
	memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf));
	adapter->event_cause = 0;
	adapter->region_code = 0;
	adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
	adapter->adhoc_awake_period = 0;
	memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
	adapter->arp_filter_size = 0;
}

/*
 * This function sets trans_start per tx_queue
 */
void mwifiex_set_trans_start(struct net_device *dev)
{
	int i;

	for (i = 0; i < dev->num_tx_queues; i++)
		netdev_get_tx_queue(dev, i)->trans_start = jiffies;

	dev->trans_start = jiffies;
}

/*
 * This function wakes up all queues in net_device
 */
void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
					struct mwifiex_adapter *adapter)
{
	unsigned long dev_queue_flags;

	spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
	netif_tx_wake_all_queues(netdev);
	spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
}

/*
 * This function stops all queues in net_device
 */
void mwifiex_stop_net_dev_queue(struct net_device *netdev,
					struct mwifiex_adapter *adapter)
{
	unsigned long dev_queue_flags;

	spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
	netif_tx_stop_all_queues(netdev);
	spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
}

/*
 *  This function releases the lock variables and frees the locks and
 *  associated locks.
 */
static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
{
	struct mwifiex_private *priv;
	s32 i, j;

	/* Free lists */
	list_del(&adapter->cmd_free_q);
	list_del(&adapter->cmd_pending_q);
	list_del(&adapter->scan_pending_q);

	for (i = 0; i < adapter->priv_num; i++)
		list_del(&adapter->bss_prio_tbl[i].bss_prio_head);

	for (i = 0; i < adapter->priv_num; i++) {
		if (adapter->priv[i]) {
			priv = adapter->priv[i];
			for (j = 0; j < MAX_NUM_TID; ++j)
				list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
			list_del(&priv->tx_ba_stream_tbl_ptr);
			list_del(&priv->rx_reorder_tbl_ptr);
		}
	}
}

/*
 * This function frees the adapter structure.
 *
 * The freeing operation is done recursively, by canceling all
 * pending commands, freeing the member buffers previously
 * allocated (command buffers, scan table buffer, sleep confirm
 * command buffer), stopping the timers and calling the cleanup
 * routines for every interface, before the actual adapter
 * structure is freed.
 */
static void
mwifiex_free_adapter(struct mwifiex_adapter *adapter)
{
	if (!adapter) {
		pr_err("%s: adapter is NULL\n", __func__);
		return;
	}

	mwifiex_cancel_all_pending_cmd(adapter);

	/* Free lock variables */
	mwifiex_free_lock_list(adapter);

	/* Free command buffer */
	dev_dbg(adapter->dev, "info: free cmd buffer\n");
	mwifiex_free_cmd_buffer(adapter);

	del_timer(&adapter->cmd_timer);

	dev_dbg(adapter->dev, "info: free scan table\n");

	adapter->if_ops.cleanup_if(adapter);

	dev_kfree_skb_any(adapter->sleep_cfm);
}

/*
 *  This function intializes the lock variables and
 *  the list heads.
 */
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
{
	struct mwifiex_private *priv;
	s32 i, j;

	spin_lock_init(&adapter->mwifiex_lock);
	spin_lock_init(&adapter->int_lock);
	spin_lock_init(&adapter->main_proc_lock);
	spin_lock_init(&adapter->mwifiex_cmd_lock);
	spin_lock_init(&adapter->queue_lock);
	for (i = 0; i < adapter->priv_num; i++) {
		if (adapter->priv[i]) {
			priv = adapter->priv[i];
			spin_lock_init(&priv->rx_pkt_lock);
			spin_lock_init(&priv->wmm.ra_list_spinlock);
			spin_lock_init(&priv->curr_bcn_buf_lock);
		}
	}

	/* Initialize cmd_free_q */
	INIT_LIST_HEAD(&adapter->cmd_free_q);
	/* Initialize cmd_pending_q */
	INIT_LIST_HEAD(&adapter->cmd_pending_q);
	/* Initialize scan_pending_q */
	INIT_LIST_HEAD(&adapter->scan_pending_q);

	spin_lock_init(&adapter->cmd_free_q_lock);
	spin_lock_init(&adapter->cmd_pending_q_lock);
	spin_lock_init(&adapter->scan_pending_q_lock);

	for (i = 0; i < adapter->priv_num; ++i) {
		INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
		adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
		spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
	}

	for (i = 0; i < adapter->priv_num; i++) {
		if (!adapter->priv[i])
			continue;
		priv = adapter->priv[i];
		for (j = 0; j < MAX_NUM_TID; ++j) {
			INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
			spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock);
		}
		INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
		INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);

		spin_lock_init(&priv->tx_ba_stream_tbl_lock);
		spin_lock_init(&priv->rx_reorder_tbl_lock);
	}

	return 0;
}

/*
 * This function initializes the firmware.
 *
 * The following operations are performed sequentially -
 *      - Allocate adapter structure
 *      - Initialize the adapter structure
 *      - Initialize the private structure
 *      - Add BSS priority tables to the adapter structure
 *      - For each interface, send the init commands to firmware
 *      - Send the first command in command pending queue, if available
 */
int mwifiex_init_fw(struct mwifiex_adapter *adapter)
{
	int ret;
	struct mwifiex_private *priv;
	u8 i, first_sta = true;
	int is_cmd_pend_q_empty;
	unsigned long flags;

	adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;

	/* Allocate memory for member of adapter structure */
	ret = mwifiex_allocate_adapter(adapter);
	if (ret)
		return -1;

	/* Initialize adapter structure */
	mwifiex_init_adapter(adapter);

	for (i = 0; i < adapter->priv_num; i++) {
		if (adapter->priv[i]) {
			priv = adapter->priv[i];

			/* Initialize private structure */
			ret = mwifiex_init_priv(priv);
			if (ret)
				return -1;
		}
	}
	for (i = 0; i < adapter->priv_num; i++) {
		if (adapter->priv[i]) {
			ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta);
			if (ret == -1)
				return -1;

			first_sta = false;
		}
	}

	spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
	is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
	if (!is_cmd_pend_q_empty) {
		/* Send the first command in queue and return */
		if (mwifiex_main_process(adapter) != -1)
			ret = -EINPROGRESS;
	} else {
		adapter->hw_status = MWIFIEX_HW_STATUS_READY;
	}

	return ret;
}

/*
 * This function deletes the BSS priority tables.
 *
 * The function traverses through all the allocated BSS priority nodes
 * in every BSS priority table and frees them.
 */
static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
{
	int i;
	struct mwifiex_adapter *adapter = priv->adapter;
	struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur;
	struct list_head *head;
	spinlock_t *lock;
	unsigned long flags;

	for (i = 0; i < adapter->priv_num; ++i) {
		head = &adapter->bss_prio_tbl[i].bss_prio_head;
		cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
		lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
		dev_dbg(adapter->dev, "info: delete BSS priority table,"
				" index = %d, i = %d, head = %p, cur = %p\n",
			      priv->bss_index, i, head, *cur);
		if (*cur) {
			spin_lock_irqsave(lock, flags);
			if (list_empty(head)) {
				spin_unlock_irqrestore(lock, flags);
				continue;
			}
			bssprio_node = list_first_entry(head,
					struct mwifiex_bss_prio_node, list);
			spin_unlock_irqrestore(lock, flags);

			list_for_each_entry_safe(bssprio_node, tmp_node, head,
						 list) {
				if (bssprio_node->priv == priv) {
					dev_dbg(adapter->dev, "info: Delete "
						"node %p, next = %p\n",
						bssprio_node, tmp_node);
					spin_lock_irqsave(lock, flags);
					list_del(&bssprio_node->list);
					spin_unlock_irqrestore(lock, flags);
					kfree(bssprio_node);
				}
			}
			*cur = (struct mwifiex_bss_prio_node *)head;
		}
	}
}

/*
 * This function is used to shutdown the driver.
 *
 * The following operations are performed sequentially -
 *      - Check if already shut down
 *      - Make sure the main process has stopped
 *      - Clean up the Tx and Rx queues
 *      - Delete BSS priority tables
 *      - Free the adapter
 *      - Notify completion
 */
int
mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
{
	int ret = -EINPROGRESS;
	struct mwifiex_private *priv;
	s32 i;
	unsigned long flags;

	/* mwifiex already shutdown */
	if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
		return 0;

	adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING;
	/* wait for mwifiex_process to complete */
	if (adapter->mwifiex_processing) {
		dev_warn(adapter->dev, "main process is still running\n");
		return ret;
	}

	/* shut down mwifiex */
	dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");

	/* Clean up Tx/Rx queues and delete BSS priority table */
	for (i = 0; i < adapter->priv_num; i++) {
		if (adapter->priv[i]) {
			priv = adapter->priv[i];

			mwifiex_clean_txrx(priv);
			mwifiex_delete_bss_prio_tbl(priv);
		}
	}

	spin_lock_irqsave(&adapter->mwifiex_lock, flags);

	/* Free adapter structure */
	mwifiex_free_adapter(adapter);

	spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);

	/* Notify completion */
	ret = mwifiex_shutdown_fw_complete(adapter);

	return ret;
}

/*
 * This function downloads the firmware to the card.
 *
 * The actual download is preceded by two sanity checks -
 *      - Check if firmware is already running
 *      - Check if the interface is the winner to download the firmware
 *
 * ...and followed by another -
 *      - Check if the firmware is downloaded successfully
 *
 * After download is successfully completed, the host interrupts are enabled.
 */
int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
		    struct mwifiex_fw_image *pmfw)
{
	int ret;
	u32 poll_num = 1;

	adapter->winner = 0;

	/* Check if firmware is already running */
	ret = adapter->if_ops.check_fw_status(adapter, poll_num);
	if (!ret) {
		dev_notice(adapter->dev,
				"WLAN FW already running! Skip FW download\n");
		goto done;
	}
	poll_num = MAX_FIRMWARE_POLL_TRIES;

	/* Check if we are the winner for downloading FW */
	if (!adapter->winner) {
		dev_notice(adapter->dev,
				"Other interface already running!"
				" Skip FW download\n");
		poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
		goto poll_fw;
	}
	if (pmfw) {
		/* Download firmware with helper */
		ret = adapter->if_ops.prog_fw(adapter, pmfw);
		if (ret) {
			dev_err(adapter->dev, "prog_fw failed ret=%#x\n", ret);
			return ret;
		}
	}

poll_fw:
	/* Check if the firmware is downloaded successfully or not */
	ret = adapter->if_ops.check_fw_status(adapter, poll_num);
	if (ret) {
		dev_err(adapter->dev, "FW failed to be active in time\n");
		return -1;
	}
done:
	/* re-enable host interrupt for mwifiex after fw dnld is successful */
	adapter->if_ops.enable_int(adapter);
	return ret;
}
