/* ZD1211 USB-WLAN driver for Linux
 *
 * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
 * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/* This file implements all the hardware specific functions for the ZD1211
 * and ZD1211B chips. Support for the ZD1211B was possible after Timothy
 * Legge sent me a ZD1211B device. Thank you Tim. -- Uli
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>

#include "zd_def.h"
#include "zd_chip.h"
#include "zd_mac.h"
#include "zd_rf.h"

void zd_chip_init(struct zd_chip *chip,
	         struct ieee80211_hw *hw,
		 struct usb_interface *intf)
{
	memset(chip, 0, sizeof(*chip));
	mutex_init(&chip->mutex);
	zd_usb_init(&chip->usb, hw, intf);
	zd_rf_init(&chip->rf);
}

void zd_chip_clear(struct zd_chip *chip)
{
	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
	zd_usb_clear(&chip->usb);
	zd_rf_clear(&chip->rf);
	mutex_destroy(&chip->mutex);
	ZD_MEMCLEAR(chip, sizeof(*chip));
}

static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
{
	u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip));
	return scnprintf(buffer, size, "%02x-%02x-%02x",
		         addr[0], addr[1], addr[2]);
}

/* Prints an identifier line, which will support debugging. */
static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
{
	int i = 0;

	i = scnprintf(buffer, size, "zd1211%s chip ",
		      zd_chip_is_zd1211b(chip) ? "b" : "");
	i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
	i += scnprintf(buffer+i, size-i, " ");
	i += scnprint_mac_oui(chip, buffer+i, size-i);
	i += scnprintf(buffer+i, size-i, " ");
	i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
	i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
		chip->patch_cck_gain ? 'g' : '-',
		chip->patch_cr157 ? '7' : '-',
		chip->patch_6m_band_edge ? '6' : '-',
		chip->new_phy_layout ? 'N' : '-',
		chip->al2230s_bit ? 'S' : '-');
	return i;
}

static void print_id(struct zd_chip *chip)
{
	char buffer[80];

	scnprint_id(chip, buffer, sizeof(buffer));
	buffer[sizeof(buffer)-1] = 0;
	dev_info(zd_chip_dev(chip), "%s\n", buffer);
}

static zd_addr_t inc_addr(zd_addr_t addr)
{
	u16 a = (u16)addr;
	/* Control registers use byte addressing, but everything else uses word
	 * addressing. */
	if ((a & 0xf000) == CR_START)
		a += 2;
	else
		a += 1;
	return (zd_addr_t)a;
}

/* Read a variable number of 32-bit values. Parameter count is not allowed to
 * exceed USB_MAX_IOREAD32_COUNT.
 */
int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
		 unsigned int count)
{
	int r;
	int i;
	zd_addr_t *a16;
	u16 *v16;
	unsigned int count16;

	if (count > USB_MAX_IOREAD32_COUNT)
		return -EINVAL;

	/* Allocate a single memory block for values and addresses. */
	count16 = 2*count;
	/* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */
	a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
		                   GFP_KERNEL);
	if (!a16) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error ENOMEM in allocation of a16\n");
		r = -ENOMEM;
		goto out;
	}
	v16 = (u16 *)(a16 + count16);

	for (i = 0; i < count; i++) {
		int j = 2*i;
		/* We read the high word always first. */
		a16[j] = inc_addr(addr[i]);
		a16[j+1] = addr[i];
	}

	r = zd_ioread16v_locked(chip, v16, a16, count16);
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error: zd_ioread16v_locked. Error number %d\n", r);
		goto out;
	}

	for (i = 0; i < count; i++) {
		int j = 2*i;
		values[i] = (v16[j] << 16) | v16[j+1];
	}

out:
	kfree((void *)a16);
	return r;
}

int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
	           unsigned int count)
{
	int i, j, r;
	struct zd_ioreq16 *ioreqs16;
	unsigned int count16;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));

	if (count == 0)
		return 0;
	if (count > USB_MAX_IOWRITE32_COUNT)
		return -EINVAL;

	/* Allocate a single memory block for values and addresses. */
	count16 = 2*count;
	ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL);
	if (!ioreqs16) {
		r = -ENOMEM;
		dev_dbg_f(zd_chip_dev(chip),
			  "error %d in ioreqs16 allocation\n", r);
		goto out;
	}

	for (i = 0; i < count; i++) {
		j = 2*i;
		/* We write the high word always first. */
		ioreqs16[j].value   = ioreqs[i].value >> 16;
		ioreqs16[j].addr    = inc_addr(ioreqs[i].addr);
		ioreqs16[j+1].value = ioreqs[i].value;
		ioreqs16[j+1].addr  = ioreqs[i].addr;
	}

	r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
#ifdef DEBUG
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error %d in zd_usb_write16v\n", r);
	}
#endif /* DEBUG */
out:
	kfree(ioreqs16);
	return r;
}

int zd_iowrite16a_locked(struct zd_chip *chip,
                  const struct zd_ioreq16 *ioreqs, unsigned int count)
{
	int r;
	unsigned int i, j, t, max;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	for (i = 0; i < count; i += j + t) {
		t = 0;
		max = count-i;
		if (max > USB_MAX_IOWRITE16_COUNT)
			max = USB_MAX_IOWRITE16_COUNT;
		for (j = 0; j < max; j++) {
			if (!ioreqs[i+j].addr) {
				t = 1;
				break;
			}
		}

		r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
		if (r) {
			dev_dbg_f(zd_chip_dev(chip),
				  "error zd_usb_iowrite16v. Error number %d\n",
				  r);
			return r;
		}
	}

	return 0;
}

/* Writes a variable number of 32 bit registers. The functions will split
 * that in several USB requests. A split can be forced by inserting an IO
 * request with an zero address field.
 */
int zd_iowrite32a_locked(struct zd_chip *chip,
	          const struct zd_ioreq32 *ioreqs, unsigned int count)
{
	int r;
	unsigned int i, j, t, max;

	for (i = 0; i < count; i += j + t) {
		t = 0;
		max = count-i;
		if (max > USB_MAX_IOWRITE32_COUNT)
			max = USB_MAX_IOWRITE32_COUNT;
		for (j = 0; j < max; j++) {
			if (!ioreqs[i+j].addr) {
				t = 1;
				break;
			}
		}

		r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
		if (r) {
			dev_dbg_f(zd_chip_dev(chip),
				"error _zd_iowrite32v_locked."
				" Error number %d\n", r);
			return r;
		}
	}

	return 0;
}

int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_ioread16_locked(chip, value, addr);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_ioread32_locked(chip, value, addr);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_iowrite16_locked(chip, value, addr);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_iowrite32_locked(chip, value, addr);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
	          u32 *values, unsigned int count)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_ioread32v_locked(chip, values, addresses, count);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
	          unsigned int count)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_iowrite32a_locked(chip, ioreqs, count);
	mutex_unlock(&chip->mutex);
	return r;
}

static int read_pod(struct zd_chip *chip, u8 *rf_type)
{
	int r;
	u32 value;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_ioread32_locked(chip, &value, E2P_POD);
	if (r)
		goto error;
	dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value);

	/* FIXME: AL2230 handling (Bit 7 in POD) */
	*rf_type = value & 0x0f;
	chip->pa_type = (value >> 16) & 0x0f;
	chip->patch_cck_gain = (value >> 8) & 0x1;
	chip->patch_cr157 = (value >> 13) & 0x1;
	chip->patch_6m_band_edge = (value >> 21) & 0x1;
	chip->new_phy_layout = (value >> 31) & 0x1;
	chip->al2230s_bit = (value >> 7) & 0x1;
	chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
	chip->supports_tx_led = 1;
	if (value & (1 << 24)) { /* LED scenario */
		if (value & (1 << 29))
			chip->supports_tx_led = 0;
	}

	dev_dbg_f(zd_chip_dev(chip),
		"RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
		"patch 6M %d new PHY %d link LED%d tx led %d\n",
		zd_rf_name(*rf_type), *rf_type,
		chip->pa_type, chip->patch_cck_gain,
		chip->patch_cr157, chip->patch_6m_band_edge,
		chip->new_phy_layout,
		chip->link_led == LED1 ? 1 : 2,
		chip->supports_tx_led);
	return 0;
error:
	*rf_type = 0;
	chip->pa_type = 0;
	chip->patch_cck_gain = 0;
	chip->patch_cr157 = 0;
	chip->patch_6m_band_edge = 0;
	chip->new_phy_layout = 0;
	return r;
}

/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and
 *              CR_MAC_ADDR_P2 must be overwritten
 */
int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
{
	int r;
	struct zd_ioreq32 reqs[2] = {
		[0] = { .addr = CR_MAC_ADDR_P1 },
		[1] = { .addr = CR_MAC_ADDR_P2 },
	};

	if (mac_addr) {
		reqs[0].value = (mac_addr[3] << 24)
			      | (mac_addr[2] << 16)
			      | (mac_addr[1] <<  8)
			      |  mac_addr[0];
		reqs[1].value = (mac_addr[5] <<  8)
			      |  mac_addr[4];
		dev_dbg_f(zd_chip_dev(chip), "mac addr %pM\n", mac_addr);
	} else {
		dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
	}

	mutex_lock(&chip->mutex);
	r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain)
{
	int r;
	u32 value;

	mutex_lock(&chip->mutex);
	r = zd_ioread32_locked(chip, &value, E2P_SUBID);
	mutex_unlock(&chip->mutex);
	if (r)
		return r;

	*regdomain = value >> 16;
	dev_dbg_f(zd_chip_dev(chip), "regdomain: %#04x\n", *regdomain);

	return 0;
}

static int read_values(struct zd_chip *chip, u8 *values, size_t count,
	               zd_addr_t e2p_addr, u32 guard)
{
	int r;
	int i;
	u32 v;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	for (i = 0;;) {
		r = zd_ioread32_locked(chip, &v,
			               (zd_addr_t)((u16)e2p_addr+i/2));
		if (r)
			return r;
		v -= guard;
		if (i+4 < count) {
			values[i++] = v;
			values[i++] = v >>  8;
			values[i++] = v >> 16;
			values[i++] = v >> 24;
			continue;
		}
		for (;i < count; i++)
			values[i] = v >> (8*(i%3));
		return 0;
	}
}

static int read_pwr_cal_values(struct zd_chip *chip)
{
	return read_values(chip, chip->pwr_cal_values,
		        E2P_CHANNEL_COUNT, E2P_PWR_CAL_VALUE1,
			0);
}

static int read_pwr_int_values(struct zd_chip *chip)
{
	return read_values(chip, chip->pwr_int_values,
		        E2P_CHANNEL_COUNT, E2P_PWR_INT_VALUE1,
			E2P_PWR_INT_GUARD);
}

static int read_ofdm_cal_values(struct zd_chip *chip)
{
	int r;
	int i;
	static const zd_addr_t addresses[] = {
		E2P_36M_CAL_VALUE1,
		E2P_48M_CAL_VALUE1,
		E2P_54M_CAL_VALUE1,
	};

	for (i = 0; i < 3; i++) {
		r = read_values(chip, chip->ofdm_cal_values[i],
				E2P_CHANNEL_COUNT, addresses[i], 0);
		if (r)
			return r;
	}
	return 0;
}

static int read_cal_int_tables(struct zd_chip *chip)
{
	int r;

	r = read_pwr_cal_values(chip);
	if (r)
		return r;
	r = read_pwr_int_values(chip);
	if (r)
		return r;
	r = read_ofdm_cal_values(chip);
	if (r)
		return r;
	return 0;
}

/* phy means physical registers */
int zd_chip_lock_phy_regs(struct zd_chip *chip)
{
	int r;
	u32 tmp;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_ioread32_locked(chip, &tmp, CR_REG1);
	if (r) {
		dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r);
		return r;
	}

	tmp &= ~UNLOCK_PHY_REGS;

	r = zd_iowrite32_locked(chip, tmp, CR_REG1);
	if (r)
		dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
	return r;
}

int zd_chip_unlock_phy_regs(struct zd_chip *chip)
{
	int r;
	u32 tmp;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_ioread32_locked(chip, &tmp, CR_REG1);
	if (r) {
		dev_err(zd_chip_dev(chip),
			"error ioread32(CR_REG1): %d\n", r);
		return r;
	}

	tmp |= UNLOCK_PHY_REGS;

	r = zd_iowrite32_locked(chip, tmp, CR_REG1);
	if (r)
		dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
	return r;
}

/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
static int patch_cr157(struct zd_chip *chip)
{
	int r;
	u16 value;

	if (!chip->patch_cr157)
		return 0;

	r = zd_ioread16_locked(chip, &value, E2P_PHY_REG);
	if (r)
		return r;

	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
	return zd_iowrite32_locked(chip, value >> 8, CR157);
}

/*
 * 6M band edge can be optionally overwritten for certain RF's
 * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge
 * bit (for AL2230, AL2230S)
 */
static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
{
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	if (!chip->patch_6m_band_edge)
		return 0;

	return zd_rf_patch_6m_band_edge(&chip->rf, channel);
}

/* Generic implementation of 6M band edge patching, used by most RFs via
 * zd_rf_generic_patch_6m() */
int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
{
	struct zd_ioreq16 ioreqs[] = {
		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
		{ CR47,  0x1e },
	};

	/* FIXME: Channel 11 is not the edge for all regulatory domains. */
	if (channel == 1 || channel == 11)
		ioreqs[0].value = 0x12;

	dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}

static int zd1211_hw_reset_phy(struct zd_chip *chip)
{
	static const struct zd_ioreq16 ioreqs[] = {
		{ CR0,   0x0a }, { CR1,   0x06 }, { CR2,   0x26 },
		{ CR3,   0x38 }, { CR4,   0x80 }, { CR9,   0xa0 },
		{ CR10,  0x81 }, { CR11,  0x00 }, { CR12,  0x7f },
		{ CR13,  0x8c }, { CR14,  0x80 }, { CR15,  0x3d },
		{ CR16,  0x20 }, { CR17,  0x1e }, { CR18,  0x0a },
		{ CR19,  0x48 }, { CR20,  0x0c }, { CR21,  0x0c },
		{ CR22,  0x23 }, { CR23,  0x90 }, { CR24,  0x14 },
		{ CR25,  0x40 }, { CR26,  0x10 }, { CR27,  0x19 },
		{ CR28,  0x7f }, { CR29,  0x80 }, { CR30,  0x4b },
		{ CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
		{ CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
		{ CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
		{ CR40,  0x84 }, { CR41,  0x2a }, { CR42,  0x80 },
		{ CR43,  0x10 }, { CR44,  0x12 }, { CR46,  0xff },
		{ CR47,  0x1E }, { CR48,  0x26 }, { CR49,  0x5b },
		{ CR64,  0xd0 }, { CR65,  0x04 }, { CR66,  0x58 },
		{ CR67,  0xc9 }, { CR68,  0x88 }, { CR69,  0x41 },
		{ CR70,  0x23 }, { CR71,  0x10 }, { CR72,  0xff },
		{ CR73,  0x32 }, { CR74,  0x30 }, { CR75,  0x65 },
		{ CR76,  0x41 }, { CR77,  0x1b }, { CR78,  0x30 },
		{ CR79,  0x68 }, { CR80,  0x64 }, { CR81,  0x64 },
		{ CR82,  0x00 }, { CR83,  0x00 }, { CR84,  0x00 },
		{ CR85,  0x02 }, { CR86,  0x00 }, { CR87,  0x00 },
		{ CR88,  0xff }, { CR89,  0xfc }, { CR90,  0x00 },
		{ CR91,  0x00 }, { CR92,  0x00 }, { CR93,  0x08 },
		{ CR94,  0x00 }, { CR95,  0x00 }, { CR96,  0xff },
		{ CR97,  0xe7 }, { CR98,  0x00 }, { CR99,  0x00 },
		{ CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
		{ CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
		{ CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
		{ CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
		{ CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
		{ CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
		{ },
		{ CR5,   0x00 }, { CR6,   0x00 }, { CR7,   0x00 },
		{ CR8,   0x00 }, { CR9,   0x20 }, { CR12,  0xf0 },
		{ CR20,  0x0e }, { CR21,  0x0e }, { CR27,  0x10 },
		{ CR44,  0x33 }, { CR47,  0x1E }, { CR83,  0x24 },
		{ CR84,  0x04 }, { CR85,  0x00 }, { CR86,  0x0C },
		{ CR87,  0x12 }, { CR88,  0x0C }, { CR89,  0x00 },
		{ CR90,  0x10 }, { CR91,  0x08 }, { CR93,  0x00 },
		{ CR94,  0x01 }, { CR95,  0x00 }, { CR96,  0x50 },
		{ CR97,  0x37 }, { CR98,  0x35 }, { CR101, 0x13 },
		{ CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
		{ CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
		{ CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
		{ CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
		{ CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
		{ CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
		{ CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
		{ CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
		{ CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
		{ CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
		{ CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
		{ CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
		{ CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
		{ CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
		{ CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
		{ CR170, 0xba }, { CR171, 0xba },
		/* Note: CR204 must lead the CR203 */
		{ CR204, 0x7d },
		{ },
		{ CR203, 0x30 },
	};

	int r, t;

	dev_dbg_f(zd_chip_dev(chip), "\n");

	r = zd_chip_lock_phy_regs(chip);
	if (r)
		goto out;

	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
	if (r)
		goto unlock;

	r = patch_cr157(chip);
unlock:
	t = zd_chip_unlock_phy_regs(chip);
	if (t && !r)
		r = t;
out:
	return r;
}

static int zd1211b_hw_reset_phy(struct zd_chip *chip)
{
	static const struct zd_ioreq16 ioreqs[] = {
		{ CR0,   0x14 }, { CR1,   0x06 }, { CR2,   0x26 },
		{ CR3,   0x38 }, { CR4,   0x80 }, { CR9,   0xe0 },
		{ CR10,  0x81 },
		/* power control { { CR11,  1 << 6 }, */
		{ CR11,  0x00 },
		{ CR12,  0xf0 }, { CR13,  0x8c }, { CR14,  0x80 },
		{ CR15,  0x3d }, { CR16,  0x20 }, { CR17,  0x1e },
		{ CR18,  0x0a }, { CR19,  0x48 },
		{ CR20,  0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
		{ CR21,  0x0e }, { CR22,  0x23 }, { CR23,  0x90 },
		{ CR24,  0x14 }, { CR25,  0x40 }, { CR26,  0x10 },
		{ CR27,  0x10 }, { CR28,  0x7f }, { CR29,  0x80 },
		{ CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
		{ CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
		{ CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
		{ CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
		{ CR40,  0x84 }, { CR41,  0x2a }, { CR42,  0x80 },
		{ CR43,  0x10 }, { CR44,  0x33 }, { CR46,  0xff },
		{ CR47,  0x1E }, { CR48,  0x26 }, { CR49,  0x5b },
		{ CR64,  0xd0 }, { CR65,  0x04 }, { CR66,  0x58 },
		{ CR67,  0xc9 }, { CR68,  0x88 }, { CR69,  0x41 },
		{ CR70,  0x23 }, { CR71,  0x10 }, { CR72,  0xff },
		{ CR73,  0x32 }, { CR74,  0x30 }, { CR75,  0x65 },
		{ CR76,  0x41 }, { CR77,  0x1b }, { CR78,  0x30 },
		{ CR79,  0xf0 }, { CR80,  0x64 }, { CR81,  0x64 },
		{ CR82,  0x00 }, { CR83,  0x24 }, { CR84,  0x04 },
		{ CR85,  0x00 }, { CR86,  0x0c }, { CR87,  0x12 },
		{ CR88,  0x0c }, { CR89,  0x00 }, { CR90,  0x58 },
		{ CR91,  0x04 }, { CR92,  0x00 }, { CR93,  0x00 },
		{ CR94,  0x01 },
		{ CR95,  0x20 }, /* ZD1211B */
		{ CR96,  0x50 }, { CR97,  0x37 }, { CR98,  0x35 },
		{ CR99,  0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
		{ CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
		{ CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
		{ CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
		{ CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
		{ CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
		{ CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
		{ CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
		{ CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
		{ CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
		{ CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
		{ CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
		{ CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
		{ CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
		{ CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
		{ CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
		{ CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
		{ CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
		{ CR170, 0xba }, { CR171, 0xba },
		/* Note: CR204 must lead the CR203 */
		{ CR204, 0x7d },
		{},
		{ CR203, 0x30 },
	};

	int r, t;

	dev_dbg_f(zd_chip_dev(chip), "\n");

	r = zd_chip_lock_phy_regs(chip);
	if (r)
		goto out;

	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
	t = zd_chip_unlock_phy_regs(chip);
	if (t && !r)
		r = t;
out:
	return r;
}

static int hw_reset_phy(struct zd_chip *chip)
{
	return zd_chip_is_zd1211b(chip) ? zd1211b_hw_reset_phy(chip) :
		                  zd1211_hw_reset_phy(chip);
}

static int zd1211_hw_init_hmac(struct zd_chip *chip)
{
	static const struct zd_ioreq32 ioreqs[] = {
		{ CR_ZD1211_RETRY_MAX,		ZD1211_RETRY_COUNT },
		{ CR_RX_THRESHOLD,		0x000c0640 },
	};

	dev_dbg_f(zd_chip_dev(chip), "\n");
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}

static int zd1211b_hw_init_hmac(struct zd_chip *chip)
{
	static const struct zd_ioreq32 ioreqs[] = {
		{ CR_ZD1211B_RETRY_MAX,		ZD1211B_RETRY_COUNT },
		{ CR_ZD1211B_CWIN_MAX_MIN_AC0,	0x007f003f },
		{ CR_ZD1211B_CWIN_MAX_MIN_AC1,	0x007f003f },
		{ CR_ZD1211B_CWIN_MAX_MIN_AC2,  0x003f001f },
		{ CR_ZD1211B_CWIN_MAX_MIN_AC3,  0x001f000f },
		{ CR_ZD1211B_AIFS_CTL1,		0x00280028 },
		{ CR_ZD1211B_AIFS_CTL2,		0x008C003C },
		{ CR_ZD1211B_TXOP,		0x01800824 },
		{ CR_RX_THRESHOLD,		0x000c0eff, },
	};

	dev_dbg_f(zd_chip_dev(chip), "\n");
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}

static int hw_init_hmac(struct zd_chip *chip)
{
	int r;
	static const struct zd_ioreq32 ioreqs[] = {
		{ CR_ACK_TIMEOUT_EXT,		0x20 },
		{ CR_ADDA_MBIAS_WARMTIME,	0x30000808 },
		{ CR_SNIFFER_ON,		0 },
		{ CR_RX_FILTER,			STA_RX_FILTER },
		{ CR_GROUP_HASH_P1,		0x00 },
		{ CR_GROUP_HASH_P2,		0x80000000 },
		{ CR_REG1,			0xa4 },
		{ CR_ADDA_PWR_DWN,		0x7f },
		{ CR_BCN_PLCP_CFG,		0x00f00401 },
		{ CR_PHY_DELAY,			0x00 },
		{ CR_ACK_TIMEOUT_EXT,		0x80 },
		{ CR_ADDA_PWR_DWN,		0x00 },
		{ CR_ACK_TIME_80211,		0x100 },
		{ CR_RX_PE_DELAY,		0x70 },
		{ CR_PS_CTRL,			0x10000000 },
		{ CR_RTS_CTS_RATE,		0x02030203 },
		{ CR_AFTER_PNP,			0x1 },
		{ CR_WEP_PROTECT,		0x114 },
		{ CR_IFS_VALUE,			IFS_VALUE_DEFAULT },
		{ CR_CAM_MODE,			MODE_AP_WDS},
	};

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
	if (r)
		return r;

	return zd_chip_is_zd1211b(chip) ?
		zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
}

struct aw_pt_bi {
	u32 atim_wnd_period;
	u32 pre_tbtt;
	u32 beacon_interval;
};

static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
{
	int r;
	static const zd_addr_t aw_pt_bi_addr[] =
		{ CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL };
	u32 values[3];

	r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
		         ARRAY_SIZE(aw_pt_bi_addr));
	if (r) {
		memset(s, 0, sizeof(*s));
		return r;
	}

	s->atim_wnd_period = values[0];
	s->pre_tbtt = values[1];
	s->beacon_interval = values[2];
	return 0;
}

static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
{
	struct zd_ioreq32 reqs[3];

	if (s->beacon_interval <= 5)
		s->beacon_interval = 5;
	if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
		s->pre_tbtt = s->beacon_interval - 1;
	if (s->atim_wnd_period >= s->pre_tbtt)
		s->atim_wnd_period = s->pre_tbtt - 1;

	reqs[0].addr = CR_ATIM_WND_PERIOD;
	reqs[0].value = s->atim_wnd_period;
	reqs[1].addr = CR_PRE_TBTT;
	reqs[1].value = s->pre_tbtt;
	reqs[2].addr = CR_BCN_INTERVAL;
	reqs[2].value = s->beacon_interval;

	return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
}


static int set_beacon_interval(struct zd_chip *chip, u32 interval)
{
	int r;
	struct aw_pt_bi s;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = get_aw_pt_bi(chip, &s);
	if (r)
		return r;
	s.beacon_interval = interval;
	return set_aw_pt_bi(chip, &s);
}

int zd_set_beacon_interval(struct zd_chip *chip, u32 interval)
{
	int r;

	mutex_lock(&chip->mutex);
	r = set_beacon_interval(chip, interval);
	mutex_unlock(&chip->mutex);
	return r;
}

static int hw_init(struct zd_chip *chip)
{
	int r;

	dev_dbg_f(zd_chip_dev(chip), "\n");
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = hw_reset_phy(chip);
	if (r)
		return r;

	r = hw_init_hmac(chip);
	if (r)
		return r;

	return set_beacon_interval(chip, 100);
}

static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
{
	return (zd_addr_t)((u16)chip->fw_regs_base + offset);
}

#ifdef DEBUG
static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
	           const char *addr_string)
{
	int r;
	u32 value;

	r = zd_ioread32_locked(chip, &value, addr);
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			"error reading %s. Error number %d\n", addr_string, r);
		return r;
	}

	dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n",
		addr_string, (unsigned int)value);
	return 0;
}

static int test_init(struct zd_chip *chip)
{
	int r;

	r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP");
	if (r)
		return r;
	r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN");
	if (r)
		return r;
	return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT");
}

static void dump_fw_registers(struct zd_chip *chip)
{
	const zd_addr_t addr[4] = {
		fw_reg_addr(chip, FW_REG_FIRMWARE_VER),
		fw_reg_addr(chip, FW_REG_USB_SPEED),
		fw_reg_addr(chip, FW_REG_FIX_TX_RATE),
		fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
	};

	int r;
	u16 values[4];

	r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr,
		         ARRAY_SIZE(addr));
	if (r) {
		dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n",
			 r);
		return;
	}

	dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]);
	dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]);
	dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]);
	dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]);
}
#endif /* DEBUG */

static int print_fw_version(struct zd_chip *chip)
{
	struct wiphy *wiphy = zd_chip_to_mac(chip)->hw->wiphy;
	int r;
	u16 version;

	r = zd_ioread16_locked(chip, &version,
		fw_reg_addr(chip, FW_REG_FIRMWARE_VER));
	if (r)
		return r;

	dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);

	snprintf(wiphy->fw_version, sizeof(wiphy->fw_version),
			"%04hx", version);

	return 0;
}

static int set_mandatory_rates(struct zd_chip *chip, int gmode)
{
	u32 rates;
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	/* This sets the mandatory rates, which only depend from the standard
	 * that the device is supporting. Until further notice we should try
	 * to support 802.11g also for full speed USB.
	 */
	if (!gmode)
		rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
	else
		rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
			CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;

	return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
}

int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
				    int preamble)
{
	u32 value = 0;

	dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble);
	value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
	value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;

	/* We always send 11M RTS/self-CTS messages, like the vendor driver. */
	value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE;
	value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE;
	value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE;
	value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;

	return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
}

int zd_chip_enable_hwint(struct zd_chip *chip)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT);
	mutex_unlock(&chip->mutex);
	return r;
}

static int disable_hwint(struct zd_chip *chip)
{
	return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT);
}

int zd_chip_disable_hwint(struct zd_chip *chip)
{
	int r;

	mutex_lock(&chip->mutex);
	r = disable_hwint(chip);
	mutex_unlock(&chip->mutex);
	return r;
}

static int read_fw_regs_offset(struct zd_chip *chip)
{
	int r;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base,
		               FWRAW_REGS_ADDR);
	if (r)
		return r;
	dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n",
		  (u16)chip->fw_regs_base);

	return 0;
}

/* Read mac address using pre-firmware interface */
int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr)
{
	dev_dbg_f(zd_chip_dev(chip), "\n");
	return zd_usb_read_fw(&chip->usb, E2P_MAC_ADDR_P1, addr,
		ETH_ALEN);
}

int zd_chip_init_hw(struct zd_chip *chip)
{
	int r;
	u8 rf_type;

	dev_dbg_f(zd_chip_dev(chip), "\n");

	mutex_lock(&chip->mutex);

#ifdef DEBUG
	r = test_init(chip);
	if (r)
		goto out;
#endif
	r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);
	if (r)
		goto out;

	r = read_fw_regs_offset(chip);
	if (r)
		goto out;

	/* GPI is always disabled, also in the other driver.
	 */
	r = zd_iowrite32_locked(chip, 0, CR_GPI_EN);
	if (r)
		goto out;
	r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX);
	if (r)
		goto out;
	/* Currently we support IEEE 802.11g for full and high speed USB.
	 * It might be discussed, whether we should suppport pure b mode for
	 * full speed USB.
	 */
	r = set_mandatory_rates(chip, 1);
	if (r)
		goto out;
	/* Disabling interrupts is certainly a smart thing here.
	 */
	r = disable_hwint(chip);
	if (r)
		goto out;
	r = read_pod(chip, &rf_type);
	if (r)
		goto out;
	r = hw_init(chip);
	if (r)
		goto out;
	r = zd_rf_init_hw(&chip->rf, rf_type);
	if (r)
		goto out;

	r = print_fw_version(chip);
	if (r)
		goto out;

#ifdef DEBUG
	dump_fw_registers(chip);
	r = test_init(chip);
	if (r)
		goto out;
#endif /* DEBUG */

	r = read_cal_int_tables(chip);
	if (r)
		goto out;

	print_id(chip);
out:
	mutex_unlock(&chip->mutex);
	return r;
}

static int update_pwr_int(struct zd_chip *chip, u8 channel)
{
	u8 value = chip->pwr_int_values[channel - 1];
	return zd_iowrite16_locked(chip, value, CR31);
}

static int update_pwr_cal(struct zd_chip *chip, u8 channel)
{
	u8 value = chip->pwr_cal_values[channel-1];
	return zd_iowrite16_locked(chip, value, CR68);
}

static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
{
	struct zd_ioreq16 ioreqs[3];

	ioreqs[0].addr = CR67;
	ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
	ioreqs[1].addr = CR66;
	ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
	ioreqs[2].addr = CR65;
	ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];

	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}

static int update_channel_integration_and_calibration(struct zd_chip *chip,
	                                              u8 channel)
{
	int r;

	if (!zd_rf_should_update_pwr_int(&chip->rf))
		return 0;

	r = update_pwr_int(chip, channel);
	if (r)
		return r;
	if (zd_chip_is_zd1211b(chip)) {
		static const struct zd_ioreq16 ioreqs[] = {
			{ CR69, 0x28 },
			{},
			{ CR69, 0x2a },
		};

		r = update_ofdm_cal(chip, channel);
		if (r)
			return r;
		r = update_pwr_cal(chip, channel);
		if (r)
			return r;
		r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
		if (r)
			return r;
	}

	return 0;
}

/* The CCK baseband gain can be optionally patched by the EEPROM */
static int patch_cck_gain(struct zd_chip *chip)
{
	int r;
	u32 value;

	if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf))
		return 0;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
	if (r)
		return r;
	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
	return zd_iowrite16_locked(chip, value & 0xff, CR47);
}

int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
{
	int r, t;

	mutex_lock(&chip->mutex);
	r = zd_chip_lock_phy_regs(chip);
	if (r)
		goto out;
	r = zd_rf_set_channel(&chip->rf, channel);
	if (r)
		goto unlock;
	r = update_channel_integration_and_calibration(chip, channel);
	if (r)
		goto unlock;
	r = patch_cck_gain(chip);
	if (r)
		goto unlock;
	r = patch_6m_band_edge(chip, channel);
	if (r)
		goto unlock;
	r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS);
unlock:
	t = zd_chip_unlock_phy_regs(chip);
	if (t && !r)
		r = t;
out:
	mutex_unlock(&chip->mutex);
	return r;
}

u8 zd_chip_get_channel(struct zd_chip *chip)
{
	u8 channel;

	mutex_lock(&chip->mutex);
	channel = chip->rf.channel;
	mutex_unlock(&chip->mutex);
	return channel;
}

int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
{
	const zd_addr_t a[] = {
		fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
		CR_LED,
	};

	int r;
	u16 v[ARRAY_SIZE(a)];
	struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
		[0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },
		[1] = { CR_LED },
	};
	u16 other_led;

	mutex_lock(&chip->mutex);
	r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
	if (r)
		goto out;

	other_led = chip->link_led == LED1 ? LED2 : LED1;

	switch (status) {
	case ZD_LED_OFF:
		ioreqs[0].value = FW_LINK_OFF;
		ioreqs[1].value = v[1] & ~(LED1|LED2);
		break;
	case ZD_LED_SCANNING:
		ioreqs[0].value = FW_LINK_OFF;
		ioreqs[1].value = v[1] & ~other_led;
		if (get_seconds() % 3 == 0) {
			ioreqs[1].value &= ~chip->link_led;
		} else {
			ioreqs[1].value |= chip->link_led;
		}
		break;
	case ZD_LED_ASSOCIATED:
		ioreqs[0].value = FW_LINK_TX;
		ioreqs[1].value = v[1] & ~other_led;
		ioreqs[1].value |= chip->link_led;
		break;
	default:
		r = -EINVAL;
		goto out;
	}

	if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
		r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
		if (r)
			goto out;
	}
	r = 0;
out:
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
{
	int r;

	if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
		return -EINVAL;

	mutex_lock(&chip->mutex);
	r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
	mutex_unlock(&chip->mutex);
	return r;
}

static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame)
{
	return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame);
}

/**
 * zd_rx_rate - report zd-rate
 * @rx_frame - received frame
 * @rx_status - rx_status as given by the device
 *
 * This function converts the rate as encoded in the received packet to the
 * zd-rate, we are using on other places in the driver.
 */
u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
{
	u8 zd_rate;
	if (status->frame_status & ZD_RX_OFDM) {
		zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame);
	} else {
		switch (zd_cck_plcp_header_signal(rx_frame)) {
		case ZD_CCK_PLCP_SIGNAL_1M:
			zd_rate = ZD_CCK_RATE_1M;
			break;
		case ZD_CCK_PLCP_SIGNAL_2M:
			zd_rate = ZD_CCK_RATE_2M;
			break;
		case ZD_CCK_PLCP_SIGNAL_5M5:
			zd_rate = ZD_CCK_RATE_5_5M;
			break;
		case ZD_CCK_PLCP_SIGNAL_11M:
			zd_rate = ZD_CCK_RATE_11M;
			break;
		default:
			zd_rate = 0;
		}
	}

	return zd_rate;
}

int zd_chip_switch_radio_on(struct zd_chip *chip)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_switch_radio_on(&chip->rf);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_chip_switch_radio_off(struct zd_chip *chip)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_switch_radio_off(&chip->rf);
	mutex_unlock(&chip->mutex);
	return r;
}

int zd_chip_enable_int(struct zd_chip *chip)
{
	int r;

	mutex_lock(&chip->mutex);
	r = zd_usb_enable_int(&chip->usb);
	mutex_unlock(&chip->mutex);
	return r;
}

void zd_chip_disable_int(struct zd_chip *chip)
{
	mutex_lock(&chip->mutex);
	zd_usb_disable_int(&chip->usb);
	mutex_unlock(&chip->mutex);
}

int zd_chip_enable_rxtx(struct zd_chip *chip)
{
	int r;

	mutex_lock(&chip->mutex);
	zd_usb_enable_tx(&chip->usb);
	r = zd_usb_enable_rx(&chip->usb);
	mutex_unlock(&chip->mutex);
	return r;
}

void zd_chip_disable_rxtx(struct zd_chip *chip)
{
	mutex_lock(&chip->mutex);
	zd_usb_disable_rx(&chip->usb);
	zd_usb_disable_tx(&chip->usb);
	mutex_unlock(&chip->mutex);
}

int zd_rfwritev_locked(struct zd_chip *chip,
	               const u32* values, unsigned int count, u8 bits)
{
	int r;
	unsigned int i;

	for (i = 0; i < count; i++) {
		r = zd_rfwrite_locked(chip, values[i], bits);
		if (r)
			return r;
	}

	return 0;
}

/*
 * We can optionally program the RF directly through CR regs, if supported by
 * the hardware. This is much faster than the older method.
 */
int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
{
	const struct zd_ioreq16 ioreqs[] = {
		{ CR244, (value >> 16) & 0xff },
		{ CR243, (value >>  8) & 0xff },
		{ CR242,  value        & 0xff },
	};
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
}

int zd_rfwritev_cr_locked(struct zd_chip *chip,
	                  const u32 *values, unsigned int count)
{
	int r;
	unsigned int i;

	for (i = 0; i < count; i++) {
		r = zd_rfwrite_cr_locked(chip, values[i]);
		if (r)
			return r;
	}

	return 0;
}

int zd_chip_set_multicast_hash(struct zd_chip *chip,
	                       struct zd_mc_hash *hash)
{
	const struct zd_ioreq32 ioreqs[] = {
		{ CR_GROUP_HASH_P1, hash->low },
		{ CR_GROUP_HASH_P2, hash->high },
	};

	return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
}

u64 zd_chip_get_tsf(struct zd_chip *chip)
{
	int r;
	static const zd_addr_t aw_pt_bi_addr[] =
		{ CR_TSF_LOW_PART, CR_TSF_HIGH_PART };
	u32 values[2];
	u64 tsf;

	mutex_lock(&chip->mutex);
	r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
	                        ARRAY_SIZE(aw_pt_bi_addr));
	mutex_unlock(&chip->mutex);
	if (r)
		return 0;

	tsf = values[1];
	tsf = (tsf << 32) | values[0];

	return tsf;
}
