/*
 * Atheros AR9170 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 "ar9170.h"
#include "cmd.h"

int ar9170_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 ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
}

int ar9170_set_slot_time(struct ar9170 *ar)
{
	u32 slottime = 20;

	if (!ar->vif)
		return 0;

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

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

int ar9170_set_basic_rates(struct ar9170 *ar)
{
	u8 cck, ofdm;

	if (!ar->vif)
		return 0;

	ofdm = ar->vif->bss_conf.basic_rates >> 4;

	/* FIXME: is still necessary? */
	if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
		cck = 0;
	else
		cck = ar->vif->bss_conf.basic_rates & 0xf;

	return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
				ofdm << 8 | cck);
}

int ar9170_set_qos(struct ar9170 *ar)
{
	ar9170_regwrite_begin(ar);

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

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

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

	ar9170_regwrite_finish();

	return ar9170_regwrite_result();
}

static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
{
	u32 val;

	/* don't allow AMPDU density > 8us */
	if (mpdudensity > 6)
		return -EINVAL;

	/* Watch out! Otus uses slightly different density values. */
	val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);

	ar9170_regwrite_begin(ar);
	ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
	ar9170_regwrite_finish();

	return ar9170_regwrite_result();
}

int ar9170_init_mac(struct ar9170 *ar)
{
	ar9170_regwrite_begin(ar);

	ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);

	ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);

	/* enable MMIC */
	ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
			AR9170_MAC_REG_SNIFFER_DEFAULTS);

	ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);

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

	/* CF-END mode */
	ar9170_regwrite(0x1c3b2c, 0x19000000);

	/* NAV protects ACK only (in TXOP) */
	ar9170_regwrite(0x1c3b38, 0x201);

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

	ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);

	/* AGG test code*/
	/* Aggregation MAX number and timeout */
	ar9170_regwrite(0x1c3b9c, 0x10000a);

	ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
			AR9170_MAC_REG_FTF_DEFAULTS);

	/* Enable deaggregator, response in sniffer mode */
	ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);

	/* rate sets */
	ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
	ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
	ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);

	/* MIMO response control */
	ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */

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

	ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);

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

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

	/* Set CPU clock frequency to 88/80MHz */
	ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
			AR9170_PWR_CLK_AHB_80_88MHZ |
			AR9170_PWR_CLK_DAC_160_INV_DLY);

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

	ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
			AR9170_MAC_FCS_FIFO_PROT);

	/* Disables the CF_END frame, undocumented register */
	ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
			0x141E0F48);

	ar9170_regwrite_finish();

	return ar9170_regwrite_result();
}

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

	if (!mac)
		mac = zero;

	ar9170_regwrite_begin(ar);

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

	ar9170_regwrite_finish();

	return ar9170_regwrite_result();
}

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

	ar9170_regwrite_begin(ar);
	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
	ar9170_regwrite_finish();
	err = ar9170_regwrite_result();
	if (err)
		return err;

	ar->cur_mc_hash = mc_hash;
	return 0;
}

int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
{
	int err;

	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
	if (err)
		return err;

	ar->cur_filter = filter;
	return 0;
}

static int ar9170_set_promiscouous(struct ar9170 *ar)
{
	u32 encr_mode, sniffer;
	int err;

	err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
	if (err)
		return err;

	err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
	if (err)
		return err;

	if (ar->sniffer_enabled) {
		sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;

		/*
		 * Rx decryption works in place.
		 *
		 * If we don't disable it, the hardware will render all
		 * encrypted frames which are encrypted with an unknown
		 * key useless.
		 */

		encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
		ar->sniffer_enabled = true;
	} else {
		sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;

		if (ar->rx_software_decryption)
			encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
		else
			encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
	}

	ar9170_regwrite_begin(ar);
	ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
	ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
	ar9170_regwrite_finish();

	return ar9170_regwrite_result();
}

int ar9170_set_operating_mode(struct ar9170 *ar)
{
	u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
	u8 *mac_addr, *bssid;
	int err;

	if (ar->vif) {
		mac_addr = ar->mac_addr;
		bssid = ar->bssid;

		switch (ar->vif->type) {
		case NL80211_IFTYPE_MESH_POINT:
		case NL80211_IFTYPE_ADHOC:
			pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
			break;
		case NL80211_IFTYPE_AP:
			pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
			break;
		case NL80211_IFTYPE_WDS:
			pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
			break;
		case NL80211_IFTYPE_MONITOR:
			ar->sniffer_enabled = true;
			ar->rx_software_decryption = true;
			break;
		default:
			pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
			break;
		}
	} else {
		mac_addr = NULL;
		bssid = NULL;
	}

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

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

	err = ar9170_set_promiscouous(ar);
	if (err)
		return err;

	/* set AMPDU density to 8us. */
	err = ar9170_set_ampdu_density(ar, 6);
	if (err)
		return err;

	ar9170_regwrite_begin(ar);

	ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
	ar9170_regwrite_finish();

	return ar9170_regwrite_result();
}

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

	return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
}

int ar9170_set_beacon_timers(struct ar9170 *ar)
{
	u32 v = 0;
	u32 pretbtt = 0;

	if (ar->vif) {
		v |= ar->vif->bss_conf.beacon_int;

		if (ar->enable_beacon) {
			switch (ar->vif->type) {
			case NL80211_IFTYPE_MESH_POINT:
			case NL80211_IFTYPE_ADHOC:
				v |= BIT(25);
				break;
			case NL80211_IFTYPE_AP:
				v |= BIT(24);
				pretbtt = (ar->vif->bss_conf.beacon_int - 6) <<
					  16;
				break;
			default:
			break;
			}
		}

		v |= ar->vif->bss_conf.dtim_period << 16;
	}

	ar9170_regwrite_begin(ar);
	ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
	ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
	ar9170_regwrite_finish();
	return ar9170_regwrite_result();
}

int ar9170_update_beacon(struct ar9170 *ar)
{
	struct sk_buff *skb;
	__le32 *data, *old = NULL;
	u32 word;
	int i;

	skb = ieee80211_beacon_get(ar->hw, ar->vif);
	if (!skb)
		return -ENOMEM;

	data = (__le32 *)skb->data;
	if (ar->beacon)
		old = (__le32 *)ar->beacon->data;

	ar9170_regwrite_begin(ar);
	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]);
		ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
	}

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

	ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
	ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
	ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);

	ar9170_regwrite_finish();

	dev_kfree_skb(ar->beacon);
	ar->beacon = skb;

	return ar9170_regwrite_result();
}

void ar9170_new_beacon(struct work_struct *work)
{
	struct ar9170 *ar = container_of(work, struct ar9170,
					 beacon_work);
	struct sk_buff *skb;

	if (unlikely(!IS_STARTED(ar)))
		return ;

	mutex_lock(&ar->mutex);

	if (!ar->vif)
		goto out;

	ar9170_update_beacon(ar);

	rcu_read_lock();
	while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
		ar9170_op_tx(ar->hw, skb);

	rcu_read_unlock();

 out:
	mutex_unlock(&ar->mutex);
}

int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
		      u8 keyidx, u8 *keydata, int keylen)
{
	__le32 vals[7];
	static const u8 bcast[ETH_ALEN] =
		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	u8 dummy;

	mac = mac ? : bcast;

	vals[0] = cpu_to_le32((keyidx << 16) + id);
	vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
	vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
			      mac[3] << 8 | mac[2]);
	memset(&vals[3], 0, 16);
	if (keydata)
		memcpy(&vals[3], keydata, keylen);

	return ar->exec_cmd(ar, AR9170_CMD_EKEY,
			    sizeof(vals), (u8 *)vals,
			    1, &dummy);
}

int ar9170_disable_key(struct ar9170 *ar, u8 id)
{
	__le32 val = cpu_to_le32(id);
	u8 dummy;

	return ar->exec_cmd(ar, AR9170_CMD_EKEY,
			    sizeof(val), (u8 *)&val,
			    1, &dummy);
}
