/**
 * Airgo MIMO wireless driver
 *
 * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>

 * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
 * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin

 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/pci.h>
#include <linux/delay.h>
#include "agnx.h"
#include "debug.h"
#include "phy.h"

unsigned int rx_frame_cnt;
/* unsigned int local_tx_sent_cnt = 0; */

static inline void disable_rx_engine(struct agnx_priv *priv)
{
	void __iomem *ctl = priv->ctl;
	iowrite32(0x100, ctl + AGNX_CIR_RXCTL);
	/* Wait for RX Control to have the Disable Rx Interrupt (0x100) set */
	ioread32(ctl + AGNX_CIR_RXCTL);
}

static inline void enable_rx_engine(struct agnx_priv *priv)
{
	void __iomem *ctl = priv->ctl;
	iowrite32(0x80, ctl + AGNX_CIR_RXCTL);
	ioread32(ctl + AGNX_CIR_RXCTL);
}

inline void disable_rx_interrupt(struct agnx_priv *priv)
{
	void __iomem *ctl = priv->ctl;
	u32 reg;

	disable_rx_engine(priv);
	reg = ioread32(ctl + AGNX_CIR_RXCFG);
	reg &= ~0x20;
	iowrite32(reg, ctl + AGNX_CIR_RXCFG);
	ioread32(ctl + AGNX_CIR_RXCFG);
}

inline void enable_rx_interrupt(struct agnx_priv *priv)
{
	void __iomem *ctl = priv->ctl;
	u32 reg;

	reg = ioread32(ctl + AGNX_CIR_RXCFG);
	reg |= 0x20;
	iowrite32(reg, ctl + AGNX_CIR_RXCFG);
	ioread32(ctl + AGNX_CIR_RXCFG);
	enable_rx_engine(priv);
}

static inline void rx_desc_init(struct agnx_priv *priv, unsigned int idx)
{
	struct agnx_desc *desc = priv->rx.desc + idx;
	struct agnx_info *info = priv->rx.info + idx;

	memset(info, 0, sizeof(*info));

	info->dma_len = IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct agnx_hdr);
	info->skb = dev_alloc_skb(info->dma_len);
	if (info->skb == NULL)
		agnx_bug("refill err");

	info->mapping = pci_map_single(priv->pdev, skb_tail_pointer(info->skb),
				       info->dma_len, PCI_DMA_FROMDEVICE);
	memset(desc, 0, sizeof(*desc));
	desc->dma_addr = cpu_to_be32(info->mapping);
	/* Set the owner to the card */
	desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
}

static inline void rx_desc_reinit(struct agnx_priv *priv, unsigned int idx)
{
	struct agnx_info *info = priv->rx.info + idx;

	/* Cause ieee80211 will free the skb buffer, so we needn't to free it again?! */
	pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
	rx_desc_init(priv, idx);
}

static inline void rx_desc_reusing(struct agnx_priv *priv, unsigned int idx)
{
	struct agnx_desc *desc = priv->rx.desc + idx;
	struct agnx_info *info = priv->rx.info + idx;

	memset(desc, 0, sizeof(*desc));
	desc->dma_addr = cpu_to_be32(info->mapping);
	/* Set the owner to the card */
	desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
}

static void rx_desc_free(struct agnx_priv *priv, unsigned int idx)
{
	struct agnx_desc *desc = priv->rx.desc + idx;
	struct agnx_info *info = priv->rx.info + idx;

	BUG_ON(!desc || !info);
	if (info->mapping)
		pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
	if (info->skb)
		dev_kfree_skb(info->skb);
	memset(info, 0, sizeof(*info));
	memset(desc, 0, sizeof(*desc));
}

static inline void __tx_desc_free(struct agnx_priv *priv,
				  struct agnx_desc *desc, struct agnx_info *info)
{
	BUG_ON(!desc || !info);
	/* TODO make sure mapping, skb and len are consistency */
	if (info->mapping)
		pci_unmap_single(priv->pdev, info->mapping,
				 info->dma_len, PCI_DMA_TODEVICE);
	if (info->type == PACKET)
		dev_kfree_skb(info->skb);

	memset(info, 0, sizeof(*info));
	memset(desc, 0, sizeof(*desc));
}

static void txm_desc_free(struct agnx_priv *priv, unsigned int idx)
{
	struct agnx_desc *desc = priv->txm.desc + idx;
	struct agnx_info *info = priv->txm.info + idx;

	__tx_desc_free(priv, desc, info);
}

static void txd_desc_free(struct agnx_priv *priv, unsigned int idx)
{
	struct agnx_desc *desc = priv->txd.desc + idx;
	struct agnx_info *info = priv->txd.info + idx;

	__tx_desc_free(priv, desc, info);
}

int fill_rings(struct agnx_priv *priv)
{
	void __iomem *ctl = priv->ctl;
	unsigned int i;
	u32 reg;
	AGNX_TRACE;

	priv->txd.idx_sent = priv->txm.idx_sent = 0;
	priv->rx.idx = priv->txm.idx = priv->txd.idx = 0;

	for (i = 0; i < priv->rx.size; i++)
		rx_desc_init(priv, i);
	for (i = 0; i < priv->txm.size; i++) {
		memset(priv->txm.desc + i, 0, sizeof(struct agnx_desc));
		memset(priv->txm.info + i, 0, sizeof(struct agnx_info));
	}
	for (i = 0; i < priv->txd.size; i++) {
		memset(priv->txd.desc + i, 0, sizeof(struct agnx_desc));
		memset(priv->txd.info + i, 0, sizeof(struct agnx_info));
	}

	/* FIXME Set the card RX TXM and TXD address */
	agnx_write32(ctl, AGNX_CIR_RXCMSTART, priv->rx.dma);
	agnx_write32(ctl, AGNX_CIR_RXCMEND, priv->txm.dma);

	agnx_write32(ctl, AGNX_CIR_TXMSTART, priv->txm.dma);
	agnx_write32(ctl, AGNX_CIR_TXMEND, priv->txd.dma);

	agnx_write32(ctl, AGNX_CIR_TXDSTART, priv->txd.dma);
	agnx_write32(ctl, AGNX_CIR_TXDEND, priv->txd.dma +
		     sizeof(struct agnx_desc) * priv->txd.size);

	/* FIXME Relinquish control of rings to card */
	reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
	reg &= ~0x800;
	agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
	return 0;
} /* fill_rings */

void unfill_rings(struct agnx_priv *priv)
{
	unsigned long flags;
	unsigned int i;
	AGNX_TRACE;

	spin_lock_irqsave(&priv->lock, flags);

	for (i = 0; i < priv->rx.size; i++)
		rx_desc_free(priv, i);
	for (i = 0; i < priv->txm.size; i++)
		txm_desc_free(priv, i);
	for (i = 0; i < priv->txd.size; i++)
		txd_desc_free(priv, i);

	spin_unlock_irqrestore(&priv->lock, flags);
}

/* Extract the bitrate out of a CCK PLCP header.
   copy from bcm43xx driver */
static inline u8 agnx_plcp_get_bitrate_cck(__be32 *phyhdr_11b)
{
	/* FIXME */
	switch (*(u8 *)phyhdr_11b) {
	case 0x0A:
		return 0;
	case 0x14:
		return 1;
	case 0x37:
		return 2;
	case 0x6E:
		return 3;
	}
	agnx_bug("Wrong plcp rate");
	return 0;
}

/* FIXME */
static inline u8 agnx_plcp_get_bitrate_ofdm(__be32 *phyhdr_11g)
{
	u8 rate = *(u8 *)phyhdr_11g & 0xF;

	printk(PFX "G mode rate is 0x%x\n", rate);
	return rate;
}

/* FIXME */
static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
			 struct ieee80211_rx_status *stat)
{
	void __iomem *ctl = priv->ctl;
	u8 *rssi;
	u32 noise;
	/* FIXME just for test */
	int snr = 40;		/* signal-to-noise ratio */

	memset(stat, 0, sizeof(*stat));
	/* RSSI */
	rssi = (u8 *)&hdr->phy_stats_lo;
/*	stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
	/* Noise */
	noise = ioread32(ctl + AGNX_GCR_NOISE0);
	noise += ioread32(ctl + AGNX_GCR_NOISE1);
	noise += ioread32(ctl + AGNX_GCR_NOISE2);
	stat->noise = noise / 3;
	/* Signal quality */
/*	snr = stat->ssi - stat->noise; */
	if (snr >= 0 && snr < 40)
		stat->signal = 5 * snr / 2;
	else if (snr >= 40)
		stat->signal = 100;
	else
		stat->signal = 0;


	if (hdr->_11b0 && !hdr->_11g0) {
		stat->rate_idx = agnx_plcp_get_bitrate_cck(&hdr->_11b0);
	} else if (!hdr->_11b0 && hdr->_11g0) {
		printk(PFX "RX: Found G mode packet\n");
		stat->rate_idx = agnx_plcp_get_bitrate_ofdm(&hdr->_11g0);
	} else
		agnx_bug("Unknown packets type");


	stat->band = IEEE80211_BAND_2GHZ;
	stat->freq = agnx_channels[priv->channel - 1].center_freq;
/*	stat->antenna = 3;
	stat->mactime = be32_to_cpu(hdr->time_stamp);
	stat->channel = priv->channel; */
}

static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
				    struct sk_buff *skb)
{
	u16 fctl;
	unsigned int hdrlen;

	fctl = le16_to_cpu(ieeehdr->frame_control);
	hdrlen = ieee80211_hdrlen(fctl);
	/* FIXME */
	if (hdrlen < (2+2+6)/*minimum hdr*/ ||
	    hdrlen > sizeof(struct ieee80211_mgmt)) {
		printk(KERN_ERR PFX "hdr len is %d\n", hdrlen);
		agnx_bug("Wrong ieee80211 hdr detected");
	}
	skb_push(skb, hdrlen);
	memcpy(skb->data, ieeehdr, hdrlen);
} /* combine_hdr_frag */

static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
				    unsigned packet_len)
{
	if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
		printk(PFX "RX: CRC check fail\n");
		goto drop;
	}
	if (packet_len > 2048) {
		printk(PFX "RX: Too long packet detected\n");
		goto drop;
	}

	/* FIXME Just usable for Promious Mode, for Manage mode exclude FCS */
/* 	if (packet_len - sizeof(*agnxhdr) < FCS_LEN) { */
/* 		printk(PFX "RX: Too short packet detected\n"); */
/* 		goto drop; */
/* 	} */
	return 0;
drop:
	priv->stats.dot11FCSErrorCount++;
	return -1;
}

void handle_rx_irq(struct agnx_priv *priv)
{
	struct ieee80211_rx_status status;
	unsigned int len;
/*	AGNX_TRACE; */

	do {
		struct agnx_desc *desc;
		u32 frag;
		struct agnx_info *info;
		struct agnx_hdr *hdr;
		struct sk_buff *skb;
		unsigned int i = priv->rx.idx % priv->rx.size;

		desc = priv->rx.desc + i;
		frag = be32_to_cpu(desc->frag);
		if (frag & OWNER)
			break;

		info = priv->rx.info + i;
		skb = info->skb;
		hdr = (struct agnx_hdr *)(skb->data);

		len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
		if (agnx_packet_check(priv, hdr, len) == -1) {
			rx_desc_reusing(priv, i);
			continue;
		}
		skb_put(skb, len);

		do {
				u16 fctl;
			fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
			if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
				dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
		} while (0);

		if (hdr->_11b0 && !hdr->_11g0) {
/*			int j;
			u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
					       ->frame_control);
			if ( (fctl & IEEE80211_FCTL_FTYPE) ==  IEEE80211_FTYPE_DATA) {
				agnx_print_rx_hdr(hdr);
				agnx_print_sta(priv, BSSID_STAID);
				for (j = 0; j < 8; j++)
					agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
			} */

			get_rx_stats(priv, hdr, &status);
			skb_pull(skb, sizeof(*hdr));
			combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
		} else if (!hdr->_11b0 && hdr->_11g0) {
/*			int j; */
			agnx_print_rx_hdr(hdr);
			agnx_print_sta(priv, BSSID_STAID);
/*			for (j = 0; j < 8; j++) */
			agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);

			print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
					     skb->data, skb->len + 8);

/*			if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
			get_rx_stats(priv, hdr, &status);
			skb_pull(skb, sizeof(*hdr));
			combine_hdr_frag((struct ieee80211_hdr *)
					 ((void *)&hdr->mac_hdr), skb);
/*			dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
		} else
			agnx_bug("Unknown packets type");
		ieee80211_rx_irqsafe(priv->hw, skb, &status);
		rx_desc_reinit(priv, i);

	} while (priv->rx.idx++);
} /* handle_rx_irq */

static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
{
	struct agnx_desc *desc;
	struct agnx_info *info;
	unsigned int idx;

	for (idx = ring->idx_sent; idx < ring->idx; idx++) {
		unsigned int i = idx % ring->size;
		u32  frag;

		desc = ring->desc + i;
		info = ring->info + i;

		frag = be32_to_cpu(desc->frag);
		if (frag & OWNER) {
			if (info->type == HEADER)
				break;
			else
				agnx_bug("TX error");
		}

		pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);

		do {
/*			int j; */
			size_t len;
			len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
/*			if (len == 614) { */
/*				agnx_print_desc(desc); */
				if (info->type == PACKET) {
/*					agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
/*					agnx_print_sta_power(priv, LOCAL_STAID); */
/*					agnx_print_sta(priv, LOCAL_STAID); */
/*					for (j = 0; j < 8; j++) */
/*					agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
/*					agnx_print_sta_power(priv, BSSID_STAID); */
/*					agnx_print_sta(priv, BSSID_STAID); */
/*					for (j = 0; j < 8; j++) */
/*					agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
				}
/*			} */
		} while (0);

		if (info->type == PACKET) {
/*			dump_txm_registers(priv);
			dump_rxm_registers(priv);
			dump_bm_registers(priv);
			dump_cir_registers(priv); */
		}

		if (info->type == PACKET) {
/*			struct ieee80211_hdr *hdr; */
			struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);

			skb_pull(info->skb, sizeof(struct agnx_hdr));
			memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);

/*			dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
/* 			print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
/* 					     info->skb->data, info->skb->len); */

			if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK))
				txi->flags |= IEEE80211_TX_STAT_ACK;

			ieee80211_tx_status_irqsafe(priv->hw, info->skb);


/* 				info->tx_status.queue_number = (ring->size - i) / 2; */
/* 				ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
/* 			} else */
/* 				dev_kfree_skb_irq(info->skb); */
		}
		memset(desc, 0, sizeof(*desc));
		memset(info, 0, sizeof(*info));
	}

	ring->idx_sent = idx;
	/* TODO fill the priv->low_level_stats */

	/* ieee80211_wake_queue(priv->hw, 0); */
}

void handle_txm_irq(struct agnx_priv *priv)
{
	handle_tx_irq(priv, &priv->txm);
}

void handle_txd_irq(struct agnx_priv *priv)
{
	handle_tx_irq(priv, &priv->txd);
}

void handle_other_irq(struct agnx_priv *priv)
{
/*	void __iomem *ctl = priv->ctl; */
	u32 status = priv->irq_status;
	void __iomem *ctl = priv->ctl;
	u32 reg;

	if (status & IRQ_TX_BEACON) {
		iowrite32(IRQ_TX_BEACON, ctl + AGNX_INT_STAT);
		printk(PFX "IRQ: TX Beacon control is 0X%.8X\n", ioread32(ctl + AGNX_TXM_BEACON_CTL));
		printk(PFX "IRQ: TX Beacon rx frame num: %d\n", rx_frame_cnt);
	}
	if (status & IRQ_TX_RETRY) {
		reg = ioread32(ctl + AGNX_TXM_RETRYSTAID);
		printk(PFX "IRQ: TX Retry, RETRY STA ID is %x\n", reg);
	}
	if (status & IRQ_TX_ACTIVITY)
		printk(PFX "IRQ: TX Activity\n");
	if (status & IRQ_RX_ACTIVITY)
		printk(PFX "IRQ: RX Activity\n");
	if (status & IRQ_RX_X)
		printk(PFX "IRQ: RX X\n");
	if (status & IRQ_RX_Y) {
		reg = ioread32(ctl + AGNX_INT_MASK);
		reg &= ~IRQ_RX_Y;
		iowrite32(reg, ctl + AGNX_INT_MASK);
		iowrite32(IRQ_RX_Y, ctl + AGNX_INT_STAT);
		printk(PFX "IRQ: RX Y\n");
	}
	if (status & IRQ_RX_HASHHIT)  {
		reg = ioread32(ctl + AGNX_INT_MASK);
		reg &= ~IRQ_RX_HASHHIT;
		iowrite32(reg, ctl + AGNX_INT_MASK);
		iowrite32(IRQ_RX_HASHHIT, ctl + AGNX_INT_STAT);
		printk(PFX "IRQ: RX Hash Hit\n");

	}
	if (status & IRQ_RX_FRAME) {
		reg = ioread32(ctl + AGNX_INT_MASK);
		reg &= ~IRQ_RX_FRAME;
		iowrite32(reg, ctl + AGNX_INT_MASK);
		iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
		printk(PFX "IRQ: RX Frame\n");
		rx_frame_cnt++;
	}
	if (status & IRQ_ERR_INT) {
		iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
/*		agnx_hw_reset(priv); */
		printk(PFX "IRQ: Error Interrupt\n");
	}
	if (status & IRQ_TX_QUE_FULL)
		printk(PFX "IRQ: TX Workqueue Full\n");
	if (status & IRQ_BANDMAN_ERR)
		printk(PFX "IRQ: Bandwidth Management Error\n");
	if (status & IRQ_TX_DISABLE)
		printk(PFX "IRQ: TX Disable\n");
	if (status & IRQ_RX_IVASESKEY)
		printk(PFX "IRQ: RX Invalid Session Key\n");
	if (status & IRQ_REP_THHIT)
		printk(PFX "IRQ: Replay Threshold Hit\n");
	if (status & IRQ_TIMER1)
		printk(PFX "IRQ: Timer1\n");
	if (status & IRQ_TIMER_CNT)
		printk(PFX "IRQ: Timer Count\n");
	if (status & IRQ_PHY_FASTINT)
		printk(PFX "IRQ: Phy Fast Interrupt\n");
	if (status & IRQ_PHY_SLOWINT)
		printk(PFX "IRQ: Phy Slow Interrupt\n");
	if (status & IRQ_OTHER)
		printk(PFX "IRQ: 0x80000000\n");
} /* handle_other_irq */


static inline void route_flag_set(struct agnx_hdr *txhdr)
{
/*	u32 reg = 0; */

	/* FIXME */
/*	reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
/*	txhdr->reg5 = cpu_to_be32(reg); */
	txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
/*	txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
/*	txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
}

/* Return 0 if no match */
static inline unsigned int get_power_level(unsigned int rate, unsigned int antennas_num)
{
	unsigned int power_level;

	switch (rate) {
	case 10:
	case 20:
	case 55:
	case 60:
	case 90:
	case 120:
		power_level = 22;
		break;

	case 180:
		power_level = 19;
		break;

	case 240:
		power_level = 18;
		break;

	case 360:
		power_level = 16;
		break;

	case 480:
		power_level = 15;
		break;

	case 540:
		power_level = 14;
		break;
	default:
		agnx_bug("Error rate setting\n");
	}

	if (power_level && (antennas_num == 2))
		power_level -= 3;

	return power_level;
}

static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_info)
{
	struct agnx_hdr *txhdr = (struct agnx_hdr *)tx_info->skb->data;
	size_t len;
	u16 fc = le16_to_cpu(*(__le16 *)&tx_info->hdr);
	u32 reg;

	memset(txhdr, 0, sizeof(*txhdr));

/*	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
	reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
	txhdr->reg4 = cpu_to_be32(reg);

	/* Set the Hardware Sequence Number to 1? */
	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
/*	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
	reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
	txhdr->reg1 = cpu_to_be32(reg);
	/* Set the agnx_hdr's MAC header */
	memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);

	reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
/*	reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
/*	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
	reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
	reg |= agnx_set_bits(TM, TM_SHIFT, 0);
	txhdr->reg0 = cpu_to_be32(reg);

	/* Set the long and short retry limits */
	txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
	txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;

	/* FIXME */
	len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
	if (fc & IEEE80211_FCTL_PROTECTED)
		len += 8;
	len = 2398;
	reg = agnx_set_bits(FRAG_SIZE, FRAG_SIZE_SHIFT, len);
	len = tx_info->skb->len - sizeof(*txhdr);
	reg |= agnx_set_bits(PAYLOAD_LEN, PAYLOAD_LEN_SHIFT, len);
	txhdr->reg3 = cpu_to_be32(reg);

	route_flag_set(txhdr);
} /* fill_hdr */

static void txm_power_set(struct agnx_priv *priv,
			  struct ieee80211_tx_info *txi)
{
	struct agnx_sta_power power;
	u32 reg;

	/* FIXME */
	if (txi->control.rates[0].idx < 0) {
		/* For B mode Short Preamble */
		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
/*		control->tx_rate = -control->tx_rate; */
	} else
		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
/*		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
	reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
	reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
/*	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
	/* if rate < 11M set it to 0 */
	reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
/*	reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
/*	reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */

	power.reg = reg;
/*	power.reg = cpu_to_le32(reg); */

/*	set_sta_power(priv, &power, LOCAL_STAID); */
	set_sta_power(priv, &power, BSSID_STAID);
}

static inline int tx_packet_check(struct sk_buff *skb)
{
	unsigned int ieee_len = ieee80211_get_hdrlen_from_skb(skb);
	if (skb->len > 2048) {
		printk(KERN_ERR PFX "length is %d\n", skb->len);
		agnx_bug("Too long TX skb");
		return -1;
	}
	/* FIXME */
	if (skb->len == ieee_len) {
		printk(PFX "A strange TX packet\n");
		return -1;
		/* tx_faile_irqsafe(); */
	}
	return 0;
}

static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
		     struct agnx_ring *ring)
{
	struct agnx_desc *hdr_desc, *frag_desc;
	struct agnx_info *hdr_info, *frag_info;
	struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
	unsigned long flags;
	unsigned int i;

	spin_lock_irqsave(&priv->lock, flags);

	/* The RX interrupt need be Disable until this TX packet
	   is handled in the next tx interrupt */
	disable_rx_interrupt(priv);

	i = ring->idx;
	ring->idx += 2;
/*   	if (priv->txm_idx - priv->txm_idx_sent == AGNX_TXM_RING_SIZE - 2) */
/* 		ieee80211_stop_queue(priv->hw, 0); */

	/* Set agnx header's info and desc */
	i %= ring->size;
	hdr_desc = ring->desc + i;
	hdr_info = ring->info + i;
	hdr_info->hdr_len = ieee80211_get_hdrlen_from_skb(skb);
	memcpy(&hdr_info->hdr, skb->data, hdr_info->hdr_len);

	/* Add the agnx header to the front of the SKB */
	skb_push(skb, sizeof(struct agnx_hdr) - hdr_info->hdr_len);

	hdr_info->txi = txi;
	hdr_info->dma_len = sizeof(struct agnx_hdr);
	hdr_info->skb = skb;
	hdr_info->type = HEADER;
	fill_agnx_hdr(priv, hdr_info);
	hdr_info->mapping = pci_map_single(priv->pdev, skb->data,
					   hdr_info->dma_len, PCI_DMA_TODEVICE);
	do {
		u32 frag = 0;
		frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 1);
		frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 0);
		frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
		frag |= agnx_set_bits(FIRST_FRAG_LEN, FIRST_FRAG_LEN_SHIFT, 1);
		frag |= agnx_set_bits(OWNER, OWNER_SHIFT, 1);
		hdr_desc->frag = cpu_to_be32(frag);
	} while (0);
	hdr_desc->dma_addr = cpu_to_be32(hdr_info->mapping);


	/* Set Frag's info and desc */
	i = (i + 1) % ring->size;
	frag_desc = ring->desc + i;
	frag_info = ring->info + i;
	memcpy(frag_info, hdr_info, sizeof(struct agnx_info));
	frag_info->type = PACKET;
	frag_info->dma_len = skb->len - hdr_info->dma_len;
	frag_info->mapping = pci_map_single(priv->pdev, skb->data + hdr_info->dma_len,
					    frag_info->dma_len, PCI_DMA_TODEVICE);
	do {
		u32 frag = 0;
		frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 0);
		frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 1);
		frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
		frag |= agnx_set_bits(SUB_FRAG_LEN, SUB_FRAG_LEN_SHIFT, frag_info->dma_len);
		frag_desc->frag = cpu_to_be32(frag);
	} while (0);
	frag_desc->dma_addr = cpu_to_be32(frag_info->mapping);

	txm_power_set(priv, txi);

/*	do { */
/*		int j; */
/*		size_t len; */
/*		len = skb->len - hdr_info->dma_len + hdr_info->hdr_len;  */
/*		if (len == 614) { */
/*			agnx_print_desc(hdr_desc); */
/*			agnx_print_desc(frag_desc); */
/*			agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
/*			agnx_print_sta_power(priv, LOCAL_STAID); */
/*			agnx_print_sta(priv, LOCAL_STAID); */
/*			for (j = 0; j < 8; j++) */
/*				agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
/*			agnx_print_sta_power(priv, BSSID_STAID); */
/*			agnx_print_sta(priv, BSSID_STAID); */
/*			for (j = 0; j < 8; j++) */
/*				agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
/*			} */
/*	} while (0); */

	spin_unlock_irqrestore(&priv->lock, flags);

	/* FIXME ugly code */
	/* Trigger TXM */
	do {
		u32 reg;
		reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
		reg |= 0x8;
		iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
	} while (0);

	/* Trigger TXD */
	do {
		u32 reg;
		reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
		reg |= 0x8;
		iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
	} while (0);

	return 0;
}

int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
{
	u16 fctl;

	if (tx_packet_check(skb))
		return 0;

/*	print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
/*			     skb->data, skb->len); */

	fctl = le16_to_cpu(*((__le16 *)skb->data));

	if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
		return __agnx_tx(priv, skb, &priv->txd);
	else
		return __agnx_tx(priv, skb, &priv->txm);
}
