/* 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>
 * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net>
 * Copyright (C) 2007-2008 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
 *
 * 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
 */

#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/usb.h>
#include <linux/jiffies.h>
#include <net/ieee80211_radiotap.h>

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

struct zd_reg_alpha2_map {
	u32 reg;
	char alpha2[2];
};

static struct zd_reg_alpha2_map reg_alpha2_map[] = {
	{ ZD_REGDOMAIN_FCC, "US" },
	{ ZD_REGDOMAIN_IC, "CA" },
	{ ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */
	{ ZD_REGDOMAIN_JAPAN, "JP" },
	{ ZD_REGDOMAIN_JAPAN_ADD, "JP" },
	{ ZD_REGDOMAIN_SPAIN, "ES" },
	{ ZD_REGDOMAIN_FRANCE, "FR" },
};

/* This table contains the hardware specific values for the modulation rates. */
static const struct ieee80211_rate zd_rates[] = {
	{ .bitrate = 10,
	  .hw_value = ZD_CCK_RATE_1M, },
	{ .bitrate = 20,
	  .hw_value = ZD_CCK_RATE_2M,
	  .hw_value_short = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55,
	  .hw_value = ZD_CCK_RATE_5_5M,
	  .hw_value_short = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110,
	  .hw_value = ZD_CCK_RATE_11M,
	  .hw_value_short = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60,
	  .hw_value = ZD_OFDM_RATE_6M,
	  .flags = 0 },
	{ .bitrate = 90,
	  .hw_value = ZD_OFDM_RATE_9M,
	  .flags = 0 },
	{ .bitrate = 120,
	  .hw_value = ZD_OFDM_RATE_12M,
	  .flags = 0 },
	{ .bitrate = 180,
	  .hw_value = ZD_OFDM_RATE_18M,
	  .flags = 0 },
	{ .bitrate = 240,
	  .hw_value = ZD_OFDM_RATE_24M,
	  .flags = 0 },
	{ .bitrate = 360,
	  .hw_value = ZD_OFDM_RATE_36M,
	  .flags = 0 },
	{ .bitrate = 480,
	  .hw_value = ZD_OFDM_RATE_48M,
	  .flags = 0 },
	{ .bitrate = 540,
	  .hw_value = ZD_OFDM_RATE_54M,
	  .flags = 0 },
};

static const struct ieee80211_channel zd_channels[] = {
	{ .center_freq = 2412, .hw_value = 1 },
	{ .center_freq = 2417, .hw_value = 2 },
	{ .center_freq = 2422, .hw_value = 3 },
	{ .center_freq = 2427, .hw_value = 4 },
	{ .center_freq = 2432, .hw_value = 5 },
	{ .center_freq = 2437, .hw_value = 6 },
	{ .center_freq = 2442, .hw_value = 7 },
	{ .center_freq = 2447, .hw_value = 8 },
	{ .center_freq = 2452, .hw_value = 9 },
	{ .center_freq = 2457, .hw_value = 10 },
	{ .center_freq = 2462, .hw_value = 11 },
	{ .center_freq = 2467, .hw_value = 12 },
	{ .center_freq = 2472, .hw_value = 13 },
	{ .center_freq = 2484, .hw_value = 14 },
};

static void housekeeping_init(struct zd_mac *mac);
static void housekeeping_enable(struct zd_mac *mac);
static void housekeeping_disable(struct zd_mac *mac);

static int zd_reg2alpha2(u8 regdomain, char *alpha2)
{
	unsigned int i;
	struct zd_reg_alpha2_map *reg_map;
	for (i = 0; i < ARRAY_SIZE(reg_alpha2_map); i++) {
		reg_map = &reg_alpha2_map[i];
		if (regdomain == reg_map->reg) {
			alpha2[0] = reg_map->alpha2[0];
			alpha2[1] = reg_map->alpha2[1];
			return 0;
		}
	}
	return 1;
}

int zd_mac_preinit_hw(struct ieee80211_hw *hw)
{
	int r;
	u8 addr[ETH_ALEN];
	struct zd_mac *mac = zd_hw_mac(hw);

	r = zd_chip_read_mac_addr_fw(&mac->chip, addr);
	if (r)
		return r;

	SET_IEEE80211_PERM_ADDR(hw, addr);

	return 0;
}

int zd_mac_init_hw(struct ieee80211_hw *hw)
{
	int r;
	struct zd_mac *mac = zd_hw_mac(hw);
	struct zd_chip *chip = &mac->chip;
	char alpha2[2];
	u8 default_regdomain;

	r = zd_chip_enable_int(chip);
	if (r)
		goto out;
	r = zd_chip_init_hw(chip);
	if (r)
		goto disable_int;

	ZD_ASSERT(!irqs_disabled());

	r = zd_read_regdomain(chip, &default_regdomain);
	if (r)
		goto disable_int;
	spin_lock_irq(&mac->lock);
	mac->regdomain = mac->default_regdomain = default_regdomain;
	spin_unlock_irq(&mac->lock);

	/* We must inform the device that we are doing encryption/decryption in
	 * software at the moment. */
	r = zd_set_encryption_type(chip, ENC_SNIFFER);
	if (r)
		goto disable_int;

	r = zd_reg2alpha2(mac->regdomain, alpha2);
	if (r)
		goto disable_int;

	r = regulatory_hint(hw->wiphy, alpha2);
disable_int:
	zd_chip_disable_int(chip);
out:
	return r;
}

void zd_mac_clear(struct zd_mac *mac)
{
	flush_workqueue(zd_workqueue);
	zd_chip_clear(&mac->chip);
	ZD_ASSERT(!spin_is_locked(&mac->lock));
	ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
}

static int set_rx_filter(struct zd_mac *mac)
{
	unsigned long flags;
	u32 filter = STA_RX_FILTER;

	spin_lock_irqsave(&mac->lock, flags);
	if (mac->pass_ctrl)
		filter |= RX_FILTER_CTRL;
	spin_unlock_irqrestore(&mac->lock, flags);

	return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
}

static int set_mc_hash(struct zd_mac *mac)
{
	struct zd_mc_hash hash;
	zd_mc_clear(&hash);
	return zd_chip_set_multicast_hash(&mac->chip, &hash);
}

static int zd_op_start(struct ieee80211_hw *hw)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	struct zd_chip *chip = &mac->chip;
	struct zd_usb *usb = &chip->usb;
	int r;

	if (!usb->initialized) {
		r = zd_usb_init_hw(usb);
		if (r)
			goto out;
	}

	r = zd_chip_enable_int(chip);
	if (r < 0)
		goto out;

	r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
	if (r < 0)
		goto disable_int;
	r = set_rx_filter(mac);
	if (r)
		goto disable_int;
	r = set_mc_hash(mac);
	if (r)
		goto disable_int;
	r = zd_chip_switch_radio_on(chip);
	if (r < 0)
		goto disable_int;
	r = zd_chip_enable_rxtx(chip);
	if (r < 0)
		goto disable_radio;
	r = zd_chip_enable_hwint(chip);
	if (r < 0)
		goto disable_rxtx;

	housekeeping_enable(mac);
	return 0;
disable_rxtx:
	zd_chip_disable_rxtx(chip);
disable_radio:
	zd_chip_switch_radio_off(chip);
disable_int:
	zd_chip_disable_int(chip);
out:
	return r;
}

static void zd_op_stop(struct ieee80211_hw *hw)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	struct zd_chip *chip = &mac->chip;
	struct sk_buff *skb;
	struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue;

	/* The order here deliberately is a little different from the open()
	 * method, since we need to make sure there is no opportunity for RX
	 * frames to be processed by mac80211 after we have stopped it.
	 */

	zd_chip_disable_rxtx(chip);
	housekeeping_disable(mac);
	flush_workqueue(zd_workqueue);

	zd_chip_disable_hwint(chip);
	zd_chip_switch_radio_off(chip);
	zd_chip_disable_int(chip);


	while ((skb = skb_dequeue(ack_wait_queue)))
		dev_kfree_skb_any(skb);
}

/**
 * tx_status - reports tx status of a packet if required
 * @hw - a &struct ieee80211_hw pointer
 * @skb - a sk-buffer
 * @flags: extra flags to set in the TX status info
 * @ackssi: ACK signal strength
 * @success - True for successful transmission of the frame
 *
 * This information calls ieee80211_tx_status_irqsafe() if required by the
 * control information. It copies the control information into the status
 * information.
 *
 * If no status information has been requested, the skb is freed.
 */
static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
		      int ackssi, bool success)
{
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

	ieee80211_tx_info_clear_status(info);

	if (success)
		info->flags |= IEEE80211_TX_STAT_ACK;
	info->status.ack_signal = ackssi;
	ieee80211_tx_status_irqsafe(hw, skb);
}

/**
 * zd_mac_tx_failed - callback for failed frames
 * @dev: the mac80211 wireless device
 *
 * This function is called if a frame couldn't be succesfully be
 * transferred. The first frame from the tx queue, will be selected and
 * reported as error to the upper layers.
 */
void zd_mac_tx_failed(struct ieee80211_hw *hw)
{
	struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
	struct sk_buff *skb;

	skb = skb_dequeue(q);
	if (skb == NULL)
		return;

	tx_status(hw, skb, 0, 0);
}

/**
 * zd_mac_tx_to_dev - callback for USB layer
 * @skb: a &sk_buff pointer
 * @error: error value, 0 if transmission successful
 *
 * Informs the MAC layer that the frame has successfully transferred to the
 * device. If an ACK is required and the transfer to the device has been
 * successful, the packets are put on the @ack_wait_queue with
 * the control set removed.
 */
void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
{
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hw *hw = info->rate_driver_data[0];

	skb_pull(skb, sizeof(struct zd_ctrlset));
	if (unlikely(error ||
	    (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
		tx_status(hw, skb, 0, !error);
	} else {
		struct sk_buff_head *q =
			&zd_hw_mac(hw)->ack_wait_queue;

		skb_queue_tail(q, skb);
		while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
			zd_mac_tx_failed(hw);
	}
}

static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
{
	/* ZD_PURE_RATE() must be used to remove the modulation type flag of
	 * the zd-rate values.
	 */
	static const u8 rate_divisor[] = {
		[ZD_PURE_RATE(ZD_CCK_RATE_1M)]   =  1,
		[ZD_PURE_RATE(ZD_CCK_RATE_2M)]	 =  2,
		/* Bits must be doubled. */
		[ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11,
		[ZD_PURE_RATE(ZD_CCK_RATE_11M)]	 = 11,
		[ZD_PURE_RATE(ZD_OFDM_RATE_6M)]  =  6,
		[ZD_PURE_RATE(ZD_OFDM_RATE_9M)]  =  9,
		[ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12,
		[ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18,
		[ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24,
		[ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36,
		[ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48,
		[ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54,
	};

	u32 bits = (u32)tx_length * 8;
	u32 divisor;

	divisor = rate_divisor[ZD_PURE_RATE(zd_rate)];
	if (divisor == 0)
		return -EINVAL;

	switch (zd_rate) {
	case ZD_CCK_RATE_5_5M:
		bits = (2*bits) + 10; /* round up to the next integer */
		break;
	case ZD_CCK_RATE_11M:
		if (service) {
			u32 t = bits % 11;
			*service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION;
			if (0 < t && t <= 3) {
				*service |= ZD_PLCP_SERVICE_LENGTH_EXTENSION;
			}
		}
		bits += 10; /* round up to the next integer */
		break;
	}

	return bits/divisor;
}

static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
	                   struct ieee80211_hdr *header,
	                   struct ieee80211_tx_info *info)
{
	/*
	 * CONTROL TODO:
	 * - if backoff needed, enable bit 0
	 * - if burst (backoff not needed) disable bit 0
	 */

	cs->control = 0;

	/* First fragment */
	if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
		cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;

	/* No ACK expected (multicast, etc.) */
	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
		cs->control |= ZD_CS_NO_ACK;

	/* PS-POLL */
	if (ieee80211_is_pspoll(header->frame_control))
		cs->control |= ZD_CS_PS_POLL_FRAME;

	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
		cs->control |= ZD_CS_RTS;

	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
		cs->control |= ZD_CS_SELF_CTS;

	/* FIXME: Management frame? */
}

static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	int r;
	u32 tmp, j = 0;
	/* 4 more bytes for tail CRC */
	u32 full_len = beacon->len + 4;

	r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
	if (r < 0)
		return r;
	r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
	if (r < 0)
		return r;

	while (tmp & 0x2) {
		r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
		if (r < 0)
			return r;
		if ((++j % 100) == 0) {
			printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
			if (j >= 500)  {
				printk(KERN_ERR "Giving up beacon config.\n");
				return -ETIMEDOUT;
			}
		}
		msleep(1);
	}

	r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
	if (r < 0)
		return r;
	if (zd_chip_is_zd1211b(&mac->chip)) {
		r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
		if (r < 0)
			return r;
	}

	for (j = 0 ; j < beacon->len; j++) {
		r = zd_iowrite32(&mac->chip, CR_BCN_FIFO,
				*((u8 *)(beacon->data + j)));
		if (r < 0)
			return r;
	}

	for (j = 0; j < 4; j++) {
		r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
		if (r < 0)
			return r;
	}

	r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
	if (r < 0)
		return r;

	/* 802.11b/g 2.4G CCK 1Mb
	 * 802.11a, not yet implemented, uses different values (see GPL vendor
	 * driver)
	 */
	return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
			(full_len << 19));
}

static int fill_ctrlset(struct zd_mac *mac,
			struct sk_buff *skb)
{
	int r;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	unsigned int frag_len = skb->len + FCS_LEN;
	unsigned int packet_length;
	struct ieee80211_rate *txrate;
	struct zd_ctrlset *cs = (struct zd_ctrlset *)
		skb_push(skb, sizeof(struct zd_ctrlset));
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

	ZD_ASSERT(frag_len <= 0xffff);

	txrate = ieee80211_get_tx_rate(mac->hw, info);

	cs->modulation = txrate->hw_value;
	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
		cs->modulation = txrate->hw_value_short;

	cs->tx_length = cpu_to_le16(frag_len);

	cs_set_control(mac, cs, hdr, info);

	packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
	ZD_ASSERT(packet_length <= 0xffff);
	/* ZD1211B: Computing the length difference this way, gives us
	 * flexibility to compute the packet length.
	 */
	cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ?
			packet_length - frag_len : packet_length);

	/*
	 * CURRENT LENGTH:
	 * - transmit frame length in microseconds
	 * - seems to be derived from frame length
	 * - see Cal_Us_Service() in zdinlinef.h
	 * - if macp->bTxBurstEnable is enabled, then multiply by 4
	 *  - bTxBurstEnable is never set in the vendor driver
	 *
	 * SERVICE:
	 * - "for PLCP configuration"
	 * - always 0 except in some situations at 802.11b 11M
	 * - see line 53 of zdinlinef.h
	 */
	cs->service = 0;
	r = zd_calc_tx_length_us(&cs->service, ZD_RATE(cs->modulation),
		                 le16_to_cpu(cs->tx_length));
	if (r < 0)
		return r;
	cs->current_length = cpu_to_le16(r);
	cs->next_frame_length = 0;

	return 0;
}

/**
 * zd_op_tx - transmits a network frame to the device
 *
 * @dev: mac80211 hardware device
 * @skb: socket buffer
 * @control: the control structure
 *
 * This function transmit an IEEE 802.11 network frame to the device. The
 * control block of the skbuff will be initialized. If necessary the incoming
 * mac80211 queues will be stopped.
 */
static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	int r;

	r = fill_ctrlset(mac, skb);
	if (r)
		goto fail;

	info->rate_driver_data[0] = hw;

	r = zd_usb_tx(&mac->chip.usb, skb);
	if (r)
		goto fail;
	return 0;

fail:
	dev_kfree_skb(skb);
	return 0;
}

/**
 * filter_ack - filters incoming packets for acknowledgements
 * @dev: the mac80211 device
 * @rx_hdr: received header
 * @stats: the status for the received packet
 *
 * This functions looks for ACK packets and tries to match them with the
 * frames in the tx queue. If a match is found the frame will be dequeued and
 * the upper layers is informed about the successful transmission. If
 * mac80211 queues have been stopped and the number of frames still to be
 * transmitted is low the queues will be opened again.
 *
 * Returns 1 if the frame was an ACK, 0 if it was ignored.
 */
static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
		      struct ieee80211_rx_status *stats)
{
	struct sk_buff *skb;
	struct sk_buff_head *q;
	unsigned long flags;

	if (!ieee80211_is_ack(rx_hdr->frame_control))
		return 0;

	q = &zd_hw_mac(hw)->ack_wait_queue;
	spin_lock_irqsave(&q->lock, flags);
	skb_queue_walk(q, skb) {
		struct ieee80211_hdr *tx_hdr;

		tx_hdr = (struct ieee80211_hdr *)skb->data;
		if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN)))
		{
			__skb_unlink(skb, q);
			tx_status(hw, skb, stats->signal, 1);
			goto out;
		}
	}
out:
	spin_unlock_irqrestore(&q->lock, flags);
	return 1;
}

int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	struct ieee80211_rx_status stats;
	const struct rx_status *status;
	struct sk_buff *skb;
	int bad_frame = 0;
	__le16 fc;
	int need_padding;
	int i;
	u8 rate;

	if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
	             FCS_LEN + sizeof(struct rx_status))
		return -EINVAL;

	memset(&stats, 0, sizeof(stats));

	/* Note about pass_failed_fcs and pass_ctrl access below:
	 * mac locking intentionally omitted here, as this is the only unlocked
	 * reader and the only writer is configure_filter. Plus, if there were
	 * any races accessing these variables, it wouldn't really matter.
	 * If mac80211 ever provides a way for us to access filter flags
	 * from outside configure_filter, we could improve on this. Also, this
	 * situation may change once we implement some kind of DMA-into-skb
	 * RX path. */

	/* Caller has to ensure that length >= sizeof(struct rx_status). */
	status = (struct rx_status *)
		(buffer + (length - sizeof(struct rx_status)));
	if (status->frame_status & ZD_RX_ERROR) {
		if (mac->pass_failed_fcs &&
				(status->frame_status & ZD_RX_CRC32_ERROR)) {
			stats.flag |= RX_FLAG_FAILED_FCS_CRC;
			bad_frame = 1;
		} else {
			return -EINVAL;
		}
	}

	stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
	stats.band = IEEE80211_BAND_2GHZ;
	stats.signal = status->signal_strength;
	stats.qual = zd_rx_qual_percent(buffer,
		                          length - sizeof(struct rx_status),
		                          status);

	rate = zd_rx_rate(buffer, status);

	/* todo: return index in the big switches in zd_rx_rate instead */
	for (i = 0; i < mac->band.n_bitrates; i++)
		if (rate == mac->band.bitrates[i].hw_value)
			stats.rate_idx = i;

	length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status);
	buffer += ZD_PLCP_HEADER_SIZE;

	/* Except for bad frames, filter each frame to see if it is an ACK, in
	 * which case our internal TX tracking is updated. Normally we then
	 * bail here as there's no need to pass ACKs on up to the stack, but
	 * there is also the case where the stack has requested us to pass
	 * control frames on up (pass_ctrl) which we must consider. */
	if (!bad_frame &&
			filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats)
			&& !mac->pass_ctrl)
		return 0;

	fc = get_unaligned((__le16*)buffer);
	need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc);

	skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
	if (skb == NULL)
		return -ENOMEM;
	if (need_padding) {
		/* Make sure the the payload data is 4 byte aligned. */
		skb_reserve(skb, 2);
	}

	memcpy(skb_put(skb, length), buffer, length);

	ieee80211_rx_irqsafe(hw, skb, &stats);
	return 0;
}

static int zd_op_add_interface(struct ieee80211_hw *hw,
				struct ieee80211_if_init_conf *conf)
{
	struct zd_mac *mac = zd_hw_mac(hw);

	/* using NL80211_IFTYPE_UNSPECIFIED to indicate no mode selected */
	if (mac->type != NL80211_IFTYPE_UNSPECIFIED)
		return -EOPNOTSUPP;

	switch (conf->type) {
	case NL80211_IFTYPE_MONITOR:
	case NL80211_IFTYPE_MESH_POINT:
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_ADHOC:
		mac->type = conf->type;
		break;
	default:
		return -EOPNOTSUPP;
	}

	return zd_write_mac_addr(&mac->chip, conf->mac_addr);
}

static void zd_op_remove_interface(struct ieee80211_hw *hw,
				    struct ieee80211_if_init_conf *conf)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	mac->type = NL80211_IFTYPE_UNSPECIFIED;
	zd_set_beacon_interval(&mac->chip, 0);
	zd_write_mac_addr(&mac->chip, NULL);
}

static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	struct ieee80211_conf *conf = &hw->conf;

	return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
}

static void zd_process_intr(struct work_struct *work)
{
	u16 int_status;
	struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);

	int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
	if (int_status & INT_CFG_NEXT_BCN)
		dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
	else
		dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");

	zd_chip_enable_hwint(&mac->chip);
}


static void set_multicast_hash_handler(struct work_struct *work)
{
	struct zd_mac *mac =
		container_of(work, struct zd_mac, set_multicast_hash_work);
	struct zd_mc_hash hash;

	spin_lock_irq(&mac->lock);
	hash = mac->multicast_hash;
	spin_unlock_irq(&mac->lock);

	zd_chip_set_multicast_hash(&mac->chip, &hash);
}

static void set_rx_filter_handler(struct work_struct *work)
{
	struct zd_mac *mac =
		container_of(work, struct zd_mac, set_rx_filter_work);
	int r;

	dev_dbg_f(zd_mac_dev(mac), "\n");
	r = set_rx_filter(mac);
	if (r)
		dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r);
}

#define SUPPORTED_FIF_FLAGS \
	(FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \
	FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)
static void zd_op_configure_filter(struct ieee80211_hw *hw,
			unsigned int changed_flags,
			unsigned int *new_flags,
			int mc_count, struct dev_mc_list *mclist)
{
	struct zd_mc_hash hash;
	struct zd_mac *mac = zd_hw_mac(hw);
	unsigned long flags;
	int i;

	/* Only deal with supported flags */
	changed_flags &= SUPPORTED_FIF_FLAGS;
	*new_flags &= SUPPORTED_FIF_FLAGS;

	/* changed_flags is always populated but this driver
	 * doesn't support all FIF flags so its possible we don't
	 * need to do anything */
	if (!changed_flags)
		return;

	if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) {
		zd_mc_add_all(&hash);
	} else {
		zd_mc_clear(&hash);
		for (i = 0; i < mc_count; i++) {
			if (!mclist)
				break;
			dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n",
				  mclist->dmi_addr);
			zd_mc_add_addr(&hash, mclist->dmi_addr);
			mclist = mclist->next;
		}
	}

	spin_lock_irqsave(&mac->lock, flags);
	mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL);
	mac->pass_ctrl = !!(*new_flags & FIF_CONTROL);
	mac->multicast_hash = hash;
	spin_unlock_irqrestore(&mac->lock, flags);
	queue_work(zd_workqueue, &mac->set_multicast_hash_work);

	if (changed_flags & FIF_CONTROL)
		queue_work(zd_workqueue, &mac->set_rx_filter_work);

	/* no handling required for FIF_OTHER_BSS as we don't currently
	 * do BSSID filtering */
	/* FIXME: in future it would be nice to enable the probe response
	 * filter (so that the driver doesn't see them) until
	 * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd
	 * have to schedule work to enable prbresp reception, which might
	 * happen too late. For now we'll just listen and forward them all the
	 * time. */
}

static void set_rts_cts_work(struct work_struct *work)
{
	struct zd_mac *mac =
		container_of(work, struct zd_mac, set_rts_cts_work);
	unsigned long flags;
	unsigned int short_preamble;

	mutex_lock(&mac->chip.mutex);

	spin_lock_irqsave(&mac->lock, flags);
	mac->updating_rts_rate = 0;
	short_preamble = mac->short_preamble;
	spin_unlock_irqrestore(&mac->lock, flags);

	zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
	mutex_unlock(&mac->chip.mutex);
}

static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changes)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	unsigned long flags;
	int associated;

	dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);

	if (mac->type == NL80211_IFTYPE_MESH_POINT ||
	    mac->type == NL80211_IFTYPE_ADHOC) {
		associated = true;
		if (changes & BSS_CHANGED_BEACON) {
			struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);

			if (beacon) {
				zd_mac_config_beacon(hw, beacon);
				kfree_skb(beacon);
			}
		}

		if (changes & BSS_CHANGED_BEACON_ENABLED) {
			u32 interval;

			if (bss_conf->enable_beacon)
				interval = BCN_MODE_IBSS |
						bss_conf->beacon_int;
			else
				interval = 0;

			zd_set_beacon_interval(&mac->chip, interval);
		}
	} else
		associated = is_valid_ether_addr(bss_conf->bssid);

	spin_lock_irq(&mac->lock);
	mac->associated = associated;
	spin_unlock_irq(&mac->lock);

	/* TODO: do hardware bssid filtering */

	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
		spin_lock_irqsave(&mac->lock, flags);
		mac->short_preamble = bss_conf->use_short_preamble;
		if (!mac->updating_rts_rate) {
			mac->updating_rts_rate = 1;
			/* FIXME: should disable TX here, until work has
			 * completed and RTS_CTS reg is updated */
			queue_work(zd_workqueue, &mac->set_rts_cts_work);
		}
		spin_unlock_irqrestore(&mac->lock, flags);
	}
}

static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	return zd_chip_get_tsf(&mac->chip);
}

static const struct ieee80211_ops zd_ops = {
	.tx			= zd_op_tx,
	.start			= zd_op_start,
	.stop			= zd_op_stop,
	.add_interface		= zd_op_add_interface,
	.remove_interface	= zd_op_remove_interface,
	.config			= zd_op_config,
	.configure_filter	= zd_op_configure_filter,
	.bss_info_changed	= zd_op_bss_info_changed,
	.get_tsf		= zd_op_get_tsf,
};

struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
{
	struct zd_mac *mac;
	struct ieee80211_hw *hw;

	hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops);
	if (!hw) {
		dev_dbg_f(&intf->dev, "out of memory\n");
		return NULL;
	}

	mac = zd_hw_mac(hw);

	memset(mac, 0, sizeof(*mac));
	spin_lock_init(&mac->lock);
	mac->hw = hw;

	mac->type = NL80211_IFTYPE_UNSPECIFIED;

	memcpy(mac->channels, zd_channels, sizeof(zd_channels));
	memcpy(mac->rates, zd_rates, sizeof(zd_rates));
	mac->band.n_bitrates = ARRAY_SIZE(zd_rates);
	mac->band.bitrates = mac->rates;
	mac->band.n_channels = ARRAY_SIZE(zd_channels);
	mac->band.channels = mac->channels;

	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;

	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
		    IEEE80211_HW_SIGNAL_UNSPEC;

	hw->wiphy->interface_modes =
		BIT(NL80211_IFTYPE_MESH_POINT) |
		BIT(NL80211_IFTYPE_STATION) |
		BIT(NL80211_IFTYPE_ADHOC);

	hw->max_signal = 100;
	hw->queues = 1;
	hw->extra_tx_headroom = sizeof(struct zd_ctrlset);

	skb_queue_head_init(&mac->ack_wait_queue);

	zd_chip_init(&mac->chip, hw, intf);
	housekeeping_init(mac);
	INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
	INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
	INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
	INIT_WORK(&mac->process_intr, zd_process_intr);

	SET_IEEE80211_DEV(hw, &intf->dev);
	return hw;
}

#define LINK_LED_WORK_DELAY HZ

static void link_led_handler(struct work_struct *work)
{
	struct zd_mac *mac =
		container_of(work, struct zd_mac, housekeeping.link_led_work.work);
	struct zd_chip *chip = &mac->chip;
	int is_associated;
	int r;

	spin_lock_irq(&mac->lock);
	is_associated = mac->associated;
	spin_unlock_irq(&mac->lock);

	r = zd_chip_control_leds(chip,
		                 is_associated ? LED_ASSOCIATED : LED_SCANNING);
	if (r)
		dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);

	queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
		           LINK_LED_WORK_DELAY);
}

static void housekeeping_init(struct zd_mac *mac)
{
	INIT_DELAYED_WORK(&mac->housekeeping.link_led_work, link_led_handler);
}

static void housekeeping_enable(struct zd_mac *mac)
{
	dev_dbg_f(zd_mac_dev(mac), "\n");
	queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
			   0);
}

static void housekeeping_disable(struct zd_mac *mac)
{
	dev_dbg_f(zd_mac_dev(mac), "\n");
	cancel_rearming_delayed_workqueue(zd_workqueue,
		&mac->housekeeping.link_led_work);
	zd_chip_control_leds(&mac->chip, LED_OFF);
}
