/*
 * Atheros CARL9170 driver
 *
 * MAC programming
 *
 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, see
 * http://www.gnu.org/licenses/.
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *    Copyright (c) 2007-2008 Atheros Communications, 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 <asm/unaligned.h>

#include "carl9170.h"
#include "cmd.h"

int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
{
	u32 val;

	if (conf_is_ht40(&ar->hw->conf))
		val = 0x010a;
	else {
		if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
			val = 0x105;
		else
			val = 0x104;
	}

	return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
}

int carl9170_set_rts_cts_rate(struct ar9170 *ar)
{
	u32 rts_rate, cts_rate;

	if (conf_is_ht(&ar->hw->conf)) {
		/* 12 mbit OFDM */
		rts_rate = 0x1da;
		cts_rate = 0x10a;
	} else {
		if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
			/* 11 mbit CCK */
			rts_rate = 033;
			cts_rate = 003;
		} else {
			/* 6 mbit OFDM */
			rts_rate = 0x1bb;
			cts_rate = 0x10b;
		}
	}

	return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
				  rts_rate | (cts_rate) << 16);
}

int carl9170_set_slot_time(struct ar9170 *ar)
{
	struct ieee80211_vif *vif;
	u32 slottime = 20;

	rcu_read_lock();
	vif = carl9170_get_main_vif(ar);
	if (!vif) {
		rcu_read_unlock();
		return 0;
	}

	if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
	    vif->bss_conf.use_short_slot)
		slottime = 9;

	rcu_read_unlock();

	return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
				  slottime << 10);
}

int carl9170_set_mac_rates(struct ar9170 *ar)
{
	struct ieee80211_vif *vif;
	u32 basic, mandatory;

	rcu_read_lock();
	vif = carl9170_get_main_vif(ar);

	if (!vif) {
		rcu_read_unlock();
		return 0;
	}

	basic = (vif->bss_conf.basic_rates & 0xf);
	basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
	rcu_read_unlock();

	if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
		mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
	else
		mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */

	carl9170_regwrite_begin(ar);
	carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
	carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
	carl9170_regwrite_finish();

	return carl9170_regwrite_result();
}

int carl9170_set_qos(struct ar9170 *ar)
{
	carl9170_regwrite_begin(ar);

	carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
			  (ar->edcf[0].cw_max << 16));
	carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
			  (ar->edcf[1].cw_max << 16));
	carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
			  (ar->edcf[2].cw_max << 16));
	carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
			  (ar->edcf[3].cw_max << 16));
	carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
			  (ar->edcf[4].cw_max << 16));

	carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
			  ((ar->edcf[0].aifs * 9 + 10)) |
			  ((ar->edcf[1].aifs * 9 + 10) << 12) |
			  ((ar->edcf[2].aifs * 9 + 10) << 24));
	carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
			  ((ar->edcf[2].aifs * 9 + 10) >> 8) |
			  ((ar->edcf[3].aifs * 9 + 10) << 4) |
			  ((ar->edcf[4].aifs * 9 + 10) << 16));

	carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
			  ar->edcf[0].txop | ar->edcf[1].txop << 16);
	carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
			  ar->edcf[2].txop | ar->edcf[3].txop << 16 |
			  ar->edcf[4].txop << 24);

	carl9170_regwrite_finish();

	return carl9170_regwrite_result();
}

int carl9170_init_mac(struct ar9170 *ar)
{
	carl9170_regwrite_begin(ar);

	/* switch MAC to OTUS interface */
	carl9170_regwrite(0x1c3600, 0x3);

	carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);

	carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);

	carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
			  AR9170_MAC_FTF_MONITOR);

	/* enable MMIC */
	carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
			AR9170_MAC_SNIFFER_DEFAULTS);

	carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);

	carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
	carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
	carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);

	/* CF-END & CF-ACK rate => 24M OFDM */
	carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);

	/* NAV protects ACK only (in TXOP) */
	carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);

	/* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
	/* OTUS set AM to 0x1 */
	carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);

	carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);

	/* Aggregation MAX number and timeout */
	carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa);
	carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00);

	carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
			  AR9170_MAC_FTF_DEFAULTS);

	carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
			  AR9170_MAC_RX_CTRL_DEAGG |
			  AR9170_MAC_RX_CTRL_SHORT_FILTER);

	/* rate sets */
	carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
	carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
	carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);

	/* MIMO response control */
	carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);

	carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);

	/* set PHY register read timeout (??) */
	carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);

	/* Disable Rx TimeOut, workaround for BB. */
	carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);

	/* Set WLAN DMA interrupt mode: generate int per packet */
	carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);

	carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
			AR9170_MAC_FCS_FIFO_PROT);

	/* Disables the CF_END frame, undocumented register */
	carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
			0x141e0f48);

	/* reset group hash table */
	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);

	/* disable PRETBTT interrupt */
	carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
	carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);

	carl9170_regwrite_finish();

	return carl9170_regwrite_result();
}

static int carl9170_set_mac_reg(struct ar9170 *ar,
				const u32 reg, const u8 *mac)
{
	static const u8 zero[ETH_ALEN] = { 0 };

	if (!mac)
		mac = zero;

	carl9170_regwrite_begin(ar);

	carl9170_regwrite(reg, get_unaligned_le32(mac));
	carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));

	carl9170_regwrite_finish();

	return carl9170_regwrite_result();
}

int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
			     const u8 *mac)
{
	if (WARN_ON(id >= ar->fw.vif_num))
		return -EINVAL;

	return carl9170_set_mac_reg(ar,
		AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
}

int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
{
	int err;

	carl9170_regwrite_begin(ar);
	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
	carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
	carl9170_regwrite_finish();
	err = carl9170_regwrite_result();
	if (err)
		return err;

	ar->cur_mc_hash = mc_hash;
	return 0;
}

int carl9170_set_operating_mode(struct ar9170 *ar)
{
	struct ieee80211_vif *vif;
	struct ath_common *common = &ar->common;
	u8 *mac_addr, *bssid;
	u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
	u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS;
	u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
		      AR9170_MAC_RX_CTRL_SHORT_FILTER;
	u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
	int err = 0;

	rcu_read_lock();
	vif = carl9170_get_main_vif(ar);

	if (vif) {
		mac_addr = common->macaddr;
		bssid = common->curbssid;

		switch (vif->type) {
		case NL80211_IFTYPE_MESH_POINT:
		case NL80211_IFTYPE_ADHOC:
			cam_mode |= AR9170_MAC_CAM_IBSS;
			break;
		case NL80211_IFTYPE_AP:
			cam_mode |= AR9170_MAC_CAM_AP;

			/* iwlagn 802.11n STA Workaround */
			rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
			break;
		case NL80211_IFTYPE_WDS:
			cam_mode |= AR9170_MAC_CAM_AP_WDS;
			rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
			break;
		case NL80211_IFTYPE_STATION:
			cam_mode |= AR9170_MAC_CAM_STA;
			rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
			break;
		default:
			WARN(1, "Unsupported operation mode %x\n", vif->type);
			err = -EOPNOTSUPP;
			break;
		}
	} else {
		mac_addr = NULL;
		bssid = NULL;
	}
	rcu_read_unlock();

	if (err)
		return err;

	if (ar->rx_software_decryption)
		enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;

	if (ar->sniffer_enabled) {
		rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
		sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
		enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
	}

	err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
	if (err)
		return err;

	err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
	if (err)
		return err;

	carl9170_regwrite_begin(ar);
	carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
	carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
	carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
	carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
	carl9170_regwrite_finish();

	return carl9170_regwrite_result();
}

int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
{
	u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);

	return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
}

int carl9170_set_beacon_timers(struct ar9170 *ar)
{
	struct ieee80211_vif *vif;
	u32 v = 0;
	u32 pretbtt = 0;

	rcu_read_lock();
	vif = carl9170_get_main_vif(ar);

	if (vif) {
		struct carl9170_vif_info *mvif;
		mvif = (void *) vif->drv_priv;

		if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
			ar->global_beacon_int = vif->bss_conf.beacon_int /
						ar->beacon_enabled;

			SET_VAL(AR9170_MAC_BCN_DTIM, v,
				vif->bss_conf.dtim_period);

			switch (vif->type) {
			case NL80211_IFTYPE_MESH_POINT:
			case NL80211_IFTYPE_ADHOC:
				v |= AR9170_MAC_BCN_IBSS_MODE;
				break;
			case NL80211_IFTYPE_AP:
				v |= AR9170_MAC_BCN_AP_MODE;
				break;
			default:
				WARN_ON_ONCE(1);
				break;
			}
		} else if (vif->type == NL80211_IFTYPE_STATION) {
			ar->global_beacon_int = vif->bss_conf.beacon_int;

			SET_VAL(AR9170_MAC_BCN_DTIM, v,
				ar->hw->conf.ps_dtim_period);

			v |= AR9170_MAC_BCN_STA_PS |
			     AR9170_MAC_BCN_PWR_MGT;
		}

		if (ar->global_beacon_int) {
			if (ar->global_beacon_int < 15) {
				rcu_read_unlock();
				return -ERANGE;
			}

			ar->global_pretbtt = ar->global_beacon_int -
					CARL9170_PRETBTT_KUS;
		} else {
			ar->global_pretbtt = 0;
		}
	} else {
		ar->global_beacon_int = 0;
		ar->global_pretbtt = 0;
	}

	rcu_read_unlock();

	SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
	SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
	SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);

	carl9170_regwrite_begin(ar);
	carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
	carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
	carl9170_regwrite_finish();
	return carl9170_regwrite_result();
}

int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
{
	struct sk_buff *skb;
	struct carl9170_vif_info *cvif;
	__le32 *data, *old = NULL;
	u32 word, off, addr, len;
	int i = 0, err = 0;

	rcu_read_lock();
	cvif = rcu_dereference(ar->beacon_iter);
retry:
	if (ar->vifs == 0 || !cvif)
		goto out_unlock;

	list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
		if (cvif->active && cvif->enable_beacon)
			goto found;
	}

	if (!ar->beacon_enabled || i++)
		goto out_unlock;

	goto retry;

found:
	rcu_assign_pointer(ar->beacon_iter, cvif);

	skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
		NULL, NULL);

	if (!skb) {
		err = -ENOMEM;
		goto out_unlock;
	}

	spin_lock_bh(&ar->beacon_lock);
	data = (__le32 *)skb->data;
	if (cvif->beacon)
		old = (__le32 *)cvif->beacon->data;

	off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
	addr = ar->fw.beacon_addr + off;
	len = roundup(skb->len + FCS_LEN, 4);

	if ((off + len) > ar->fw.beacon_max_len) {
		if (net_ratelimit()) {
			wiphy_err(ar->hw->wiphy, "beacon does not "
				  "fit into device memory!\n");
		}

		spin_unlock_bh(&ar->beacon_lock);
		dev_kfree_skb_any(skb);
		err = -EINVAL;
		goto out_unlock;
	}

	if (len > AR9170_MAC_BCN_LENGTH_MAX) {
		if (net_ratelimit()) {
			wiphy_err(ar->hw->wiphy, "no support for beacons "
				"bigger than %d (yours:%d).\n",
				 AR9170_MAC_BCN_LENGTH_MAX, len);
		}

		spin_unlock_bh(&ar->beacon_lock);
		dev_kfree_skb_any(skb);
		err = -EMSGSIZE;
		goto out_unlock;
	}

	carl9170_async_regwrite_begin(ar);

	/* XXX: use skb->cb info */
	if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
		carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
				((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
	} else {
		carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
				((skb->len + FCS_LEN) << 16) + 0x001b);
	}

	for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
		/*
		 * XXX: This accesses beyond skb data for up
		 *	to the last 3 bytes!!
		 */

		if (old && (data[i] == old[i]))
			continue;

		word = le32_to_cpu(data[i]);
		carl9170_async_regwrite(addr + 4 * i, word);
	}
	carl9170_async_regwrite_finish();

	dev_kfree_skb_any(cvif->beacon);
	cvif->beacon = NULL;

	err = carl9170_async_regwrite_result();
	if (!err)
		cvif->beacon = skb;
	spin_unlock_bh(&ar->beacon_lock);
	if (err)
		goto out_unlock;

	if (submit) {
		err = carl9170_bcn_ctrl(ar, cvif->id,
					CARL9170_BCN_CTRL_CAB_TRIGGER,
					addr, skb->len + FCS_LEN);

		if (err)
			goto out_unlock;
	}
out_unlock:
	rcu_read_unlock();
	return err;
}

int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
			const u8 ktype, const u8 keyidx, const u8 *keydata,
			const int keylen)
{
	struct carl9170_set_key_cmd key = { };
	static const u8 bcast[ETH_ALEN] = {
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

	mac = mac ? : bcast;

	key.user = cpu_to_le16(id);
	key.keyId = cpu_to_le16(keyidx);
	key.type = cpu_to_le16(ktype);
	memcpy(&key.macAddr, mac, ETH_ALEN);
	if (keydata)
		memcpy(&key.key, keydata, keylen);

	return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
		sizeof(key), (u8 *)&key, 0, NULL);
}

int carl9170_disable_key(struct ar9170 *ar, const u8 id)
{
	struct carl9170_disable_key_cmd key = { };

	key.user = cpu_to_le16(id);

	return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
		sizeof(key), (u8 *)&key, 0, NULL);
}
