/**
 * 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/init.h>
#include <linux/etherdevice.h>
#include <linux/pci.h>
#include <linux/delay.h>

#include "agnx.h"
#include "debug.h"
#include "xmit.h"
#include "phy.h"

MODULE_AUTHOR("Li YanBo <dreamfly281@gmail.com>");
MODULE_DESCRIPTION("Airgo MIMO PCI wireless driver");
MODULE_LICENSE("GPL");

static struct pci_device_id agnx_pci_id_tbl[] __devinitdata = {
	{ PCI_DEVICE(0x17cb, 0x0001) },	/* Beklin F5d8010, Netgear WGM511 etc */
	{ PCI_DEVICE(0x17cb, 0x0002) },	/* Netgear Wpnt511 */
	{ 0 }
};

MODULE_DEVICE_TABLE(pci, agnx_pci_id_tbl);


static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
{
	void __iomem *ctl = priv->ctl;
	u32 reg;

	if (*reason & AGNX_STAT_RX) {
		/* Mark complete RX */
		reg = ioread32(ctl + AGNX_CIR_RXCTL);
		reg |= 0x4;
		iowrite32(reg, ctl + AGNX_CIR_RXCTL);
		/* disable Rx interrupt */
	}
	if (*reason & AGNX_STAT_TX) {
		reg = ioread32(ctl + AGNX_CIR_TXDCTL);
		if (reg & 0x4) {
			iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
			*reason |= AGNX_STAT_TXD;
		}
		reg = ioread32(ctl + AGNX_CIR_TXMCTL);
		if (reg & 0x4) {
			iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
			*reason |= AGNX_STAT_TXM;
		}
	}
#if 0
	if (*reason & AGNX_STAT_X) {
		reg = ioread32(ctl + AGNX_INT_STAT);
		iowrite32(reg, ctl + AGNX_INT_STAT);
		/* FIXME reinit interrupt mask */
		reg = 0xc390bf9 & ~IRQ_TX_BEACON;
		reg &= ~IRQ_TX_DISABLE;
		iowrite32(reg, ctl + AGNX_INT_MASK);
		iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
	}
#endif
} /* agnx_interrupt_ack */

static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
{
	struct ieee80211_hw *dev = dev_id;
	struct agnx_priv *priv = dev->priv;
	void __iomem *ctl = priv->ctl;
	irqreturn_t ret = IRQ_NONE;
	u32 irq_reason;

	spin_lock(&priv->lock);

/*	printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */

	if (priv->init_status != AGNX_START)
		goto out;

	/* FiXME  Here has no lock, Is this will lead to race? */
	irq_reason = ioread32(ctl + AGNX_CIR_BLKCTL);
	if (!(irq_reason & 0x7))
		goto out;

	ret = IRQ_HANDLED;
	priv->irq_status = ioread32(ctl + AGNX_INT_STAT);

/*	printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */
	/* Make sure the txm and txd flags don't conflict with other unknown
	   interrupt flag, maybe is not necessary */
	irq_reason &= 0xF;

	disable_rx_interrupt(priv);
	/* TODO Make sure the card finished initialized */
	agnx_interrupt_ack(priv, &irq_reason);

	if (irq_reason & AGNX_STAT_RX)
		handle_rx_irq(priv);
	if (irq_reason & AGNX_STAT_TXD)
		handle_txd_irq(priv);
	if (irq_reason & AGNX_STAT_TXM)
		handle_txm_irq(priv);
	if (irq_reason & AGNX_STAT_X)
		handle_other_irq(priv);

	enable_rx_interrupt(priv);
out:
	spin_unlock(&priv->lock);
	return ret;
} /* agnx_interrupt_handler */


/* FIXME */
static int agnx_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
	AGNX_TRACE;
	return _agnx_tx(dev->priv, skb);
} /* agnx_tx */


static int agnx_get_mac_address(struct agnx_priv *priv)
{
	void __iomem *ctl = priv->ctl;
	u32 reg;
	AGNX_TRACE;

	/* Attention! directly read the MAC or other date from EEPROM will
	 lead to cardbus(WGM511) lock up when write to PM PLL register */
	reg = agnx_read32(ctl, 0x3544);
	udelay(40);
	reg = agnx_read32(ctl, 0x354c);
	udelay(50);
	/* Get the mac address */
	reg = agnx_read32(ctl, 0x3544);
	udelay(40);

	/* HACK */
	reg = cpu_to_le32(reg);
	priv->mac_addr[0] = ((u8 *)&reg)[2];
	priv->mac_addr[1] = ((u8 *)&reg)[3];
	reg = agnx_read32(ctl, 0x3548);
	udelay(50);
	*((u32 *)(priv->mac_addr + 2)) = cpu_to_le32(reg);

	if (!is_valid_ether_addr(priv->mac_addr)) {
		printk(KERN_WARNING PFX "read mac %pM\n", priv->mac_addr);
		printk(KERN_WARNING PFX "Invalid hwaddr! Using random hwaddr\n");
		random_ether_addr(priv->mac_addr);
	}

	return 0;
} /* agnx_get_mac_address */

static int agnx_alloc_rings(struct agnx_priv *priv)
{
	unsigned int len;
	AGNX_TRACE;

	/* Allocate RX/TXM/TXD rings info */
	priv->rx.size = AGNX_RX_RING_SIZE;
	priv->txm.size = AGNX_TXM_RING_SIZE;
	priv->txd.size = AGNX_TXD_RING_SIZE;

	len = priv->rx.size + priv->txm.size + priv->txd.size;

/*	priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */
	priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
	if (!priv->rx.info)
		return -ENOMEM;
	priv->txm.info = priv->rx.info + priv->rx.size;
	priv->txd.info = priv->txm.info + priv->txm.size;

	/* Allocate RX/TXM/TXD descriptors */
	priv->rx.desc = pci_alloc_consistent(priv->pdev, sizeof(struct agnx_desc) * len,
					     &priv->rx.dma);
	if (!priv->rx.desc) {
		kfree(priv->rx.info);
		return -ENOMEM;
	}

	priv->txm.desc = priv->rx.desc + priv->rx.size;
	priv->txm.dma = priv->rx.dma + sizeof(struct agnx_desc) * priv->rx.size;
	priv->txd.desc = priv->txm.desc + priv->txm.size;
	priv->txd.dma = priv->txm.dma + sizeof(struct agnx_desc) * priv->txm.size;

	return 0;
} /* agnx_alloc_rings */

static void rings_free(struct agnx_priv *priv)
{
	unsigned int len = priv->rx.size + priv->txm.size + priv->txd.size;
	unsigned long flags;
	AGNX_TRACE;

	spin_lock_irqsave(&priv->lock, flags);
	kfree(priv->rx.info);
	pci_free_consistent(priv->pdev, sizeof(struct agnx_desc) * len,
			    priv->rx.desc, priv->rx.dma);
	spin_unlock_irqrestore(&priv->lock, flags);
}

#if 0
static void agnx_periodic_work_handler(struct work_struct *work)
{
	struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work);
/*	unsigned long flags; */
	unsigned long delay;

	/* fixme: using mutex?? */
/*	spin_lock_irqsave(&priv->lock, flags); */

	/* TODO Recalibrate*/
/*	calibrate_oscillator(priv); */
/*	antenna_calibrate(priv); */
/*	agnx_send_packet(priv, 997); */
	/* FIXME */
/* 	if (debug == 3) */
/*                 delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
/* 	else */
	delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
/*	delay = round_jiffies(HZ * 15); */

	queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);

/*	spin_unlock_irqrestore(&priv->lock, flags); */
}
#endif

static int agnx_start(struct ieee80211_hw *dev)
{
	struct agnx_priv *priv = dev->priv;
	/* unsigned long delay; */
	int err = 0;
	AGNX_TRACE;

	err = agnx_alloc_rings(priv);
	if (err) {
		printk(KERN_ERR PFX "Can't alloc RX/TXM/TXD rings\n");
		goto out;
	}
	err = request_irq(priv->pdev->irq, &agnx_interrupt_handler,
			  IRQF_SHARED, "agnx_pci", dev);
	if (err) {
		printk(KERN_ERR PFX "Failed to register IRQ handler\n");
		rings_free(priv);
		goto out;
	}

/*	mdelay(500); */

	might_sleep();
	agnx_hw_init(priv);

/*	mdelay(500); */
	might_sleep();

	priv->init_status = AGNX_START;
/*         INIT_DELAYED_WORK(&priv->periodic_work, agnx_periodic_work_handler); */
/* 	delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
/*         queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay); */
out:
	return err;
} /* agnx_start */

static void agnx_stop(struct ieee80211_hw *dev)
{
	struct agnx_priv *priv = dev->priv;
	AGNX_TRACE;

	priv->init_status = AGNX_STOP;
	/* make sure hardware will not generate irq */
	agnx_hw_reset(priv);
	free_irq(priv->pdev->irq, dev);
/*	flush_workqueue(priv->hw->workqueue); */
/*	cancel_delayed_work_sync(&priv->periodic_work); */
	unfill_rings(priv);
	rings_free(priv);
}

static int agnx_config(struct ieee80211_hw *dev, u32 changed)
{
	struct agnx_priv *priv = dev->priv;
	struct ieee80211_conf *conf = &dev->conf;
	int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
	AGNX_TRACE;

	spin_lock(&priv->lock);
	/* FIXME need priv lock? */
	if (channel != priv->channel) {
		priv->channel = channel;
		agnx_set_channel(priv, priv->channel);
	}

	spin_unlock(&priv->lock);
	return 0;
}

static void agnx_bss_info_changed(struct ieee80211_hw *dev,
				  struct ieee80211_vif *vif,
				  struct ieee80211_bss_conf *conf,
				  u32 changed)
{
	struct agnx_priv *priv = dev->priv;
	void __iomem *ctl = priv->ctl;
	AGNX_TRACE;

	if (!(changed & BSS_CHANGED_BSSID))
		return;

	spin_lock(&priv->lock);

	if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
		agnx_set_bssid(priv, conf->bssid);
		memcpy(priv->bssid, conf->bssid, ETH_ALEN);
		hash_write(priv, conf->bssid, BSSID_STAID);
		sta_init(priv, BSSID_STAID);
		/* FIXME needed? */
		sta_power_init(priv, BSSID_STAID);
		agnx_write32(ctl, AGNX_BM_MTSM, 0xff & ~0x1);
	}
	spin_unlock(&priv->lock);
} /* agnx_bss_info_changed */


static void agnx_configure_filter(struct ieee80211_hw *dev,
				  unsigned int changed_flags,
				  unsigned int *total_flags,
				  int mc_count, struct dev_mc_list *mclist)
{
	unsigned int new_flags = 0;

	*total_flags = new_flags;
	/* TODO */
}

static int agnx_add_interface(struct ieee80211_hw *dev,
			      struct ieee80211_if_init_conf *conf)
{
	struct agnx_priv *priv = dev->priv;
	AGNX_TRACE;

	spin_lock(&priv->lock);
	/* FIXME */
	if (priv->mode != NL80211_IFTYPE_MONITOR)
		return -EOPNOTSUPP;

	switch (conf->type) {
	case NL80211_IFTYPE_STATION:
		priv->mode = conf->type;
		break;
	default:
		return -EOPNOTSUPP;
	}

	spin_unlock(&priv->lock);

	return 0;
}

static void agnx_remove_interface(struct ieee80211_hw *dev,
				  struct ieee80211_if_init_conf *conf)
{
	struct agnx_priv *priv = dev->priv;
	AGNX_TRACE;

	/* TODO */
	priv->mode = NL80211_IFTYPE_MONITOR;
}

static int agnx_get_stats(struct ieee80211_hw *dev,
			  struct ieee80211_low_level_stats *stats)
{
	struct agnx_priv *priv = dev->priv;
	AGNX_TRACE;
	spin_lock(&priv->lock);
	/* TODO !! */
	memcpy(stats, &priv->stats, sizeof(*stats));
	spin_unlock(&priv->lock);

	return 0;
}

static u64 agnx_get_tsft(struct ieee80211_hw *dev)
{
	void __iomem *ctl = ((struct agnx_priv *)dev->priv)->ctl;
	u32 tsftl;
	u64 tsft;
	AGNX_TRACE;

	/* FIXME */
	tsftl = ioread32(ctl + AGNX_TXM_TIMESTAMPLO);
	tsft = ioread32(ctl + AGNX_TXM_TIMESTAMPHI);
	tsft <<= 32;
	tsft |= tsftl;

	return tsft;
}

static int agnx_get_tx_stats(struct ieee80211_hw *dev,
			     struct ieee80211_tx_queue_stats *stats)
{
	struct agnx_priv *priv = dev->priv;
	AGNX_TRACE;

	/* FIXME now we just using txd queue, but should using txm queue too */
	stats[0].len = (priv->txd.idx - priv->txd.idx_sent) / 2;
	stats[0].limit = priv->txd.size - 2;
	stats[0].count = priv->txd.idx / 2;

	return 0;
}

static struct ieee80211_ops agnx_ops = {
	.tx			= agnx_tx,
	.start			= agnx_start,
	.stop			= agnx_stop,
	.add_interface		= agnx_add_interface,
	.remove_interface	= agnx_remove_interface,
	.config			= agnx_config,
	.bss_info_changed	= agnx_bss_info_changed,
	.configure_filter	= agnx_configure_filter,
	.get_stats		= agnx_get_stats,
	.get_tx_stats		= agnx_get_tx_stats,
	.get_tsf		= agnx_get_tsft
};

static void __devexit agnx_pci_remove(struct pci_dev *pdev)
{
	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
	struct agnx_priv *priv;
	AGNX_TRACE;

	if (!dev)
		return;
	priv = dev->priv;
	ieee80211_unregister_hw(dev);
	pci_iounmap(pdev, priv->ctl);
	pci_iounmap(pdev, priv->data);
	pci_release_regions(pdev);
	pci_disable_device(pdev);

	ieee80211_free_hw(dev);
}

static int __devinit agnx_pci_probe(struct pci_dev *pdev,
				    const struct pci_device_id *id)
{
	struct ieee80211_hw *dev;
	struct agnx_priv *priv;
	int err;

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "can't enable pci device\n");
		return err;
	}

	err = pci_request_regions(pdev, "agnx-pci");
	if (err) {
		dev_err(&pdev->dev, "can't reserve PCI resources\n");
		return err;
	}

	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
		dev_err(&pdev->dev, "no suitable DMA available\n");
		err = -EIO;
		goto err_free_reg;
	}

	pci_set_master(pdev);

	dev = ieee80211_alloc_hw(sizeof(*priv), &agnx_ops);
	if (!dev) {
		dev_err(&pdev->dev, "ieee80211 alloc failed\n");
		err = -ENOMEM;
		goto err_free_reg;
	}
	priv = dev->priv;
	memset(priv, 0, sizeof(*priv));
	priv->mode = NL80211_IFTYPE_MONITOR;
	priv->pdev = pdev;
	priv->hw = dev;
	spin_lock_init(&priv->lock);
	priv->init_status = AGNX_UNINIT;

	priv->ctl = pci_iomap(pdev, 0, 0);
/*	dev_dbg(&pdev->dev, "MEM1 mapped address is 0x%p\n", priv->ctl); */
	if (!priv->ctl) {
		dev_err(&pdev->dev, "can't map device memory\n");
		err = -ENOMEM;
		goto err_free_dev;
	}
	priv->data = pci_iomap(pdev, 1, 0);
	if (!priv->data) {
		dev_err(&pdev->dev, "can't map device memory\n");
		err = -ENOMEM;
		goto err_iounmap2;
	}

	pci_read_config_byte(pdev, PCI_REVISION_ID, &priv->revid);

	priv->band.channels   = (struct ieee80211_channel *)agnx_channels;
	priv->band.n_channels = ARRAY_SIZE(agnx_channels);
	priv->band.bitrates   = (struct ieee80211_rate *)agnx_rates_80211g;
	priv->band.n_bitrates = ARRAY_SIZE(agnx_rates_80211g);

	/* Init ieee802.11 dev  */
	SET_IEEE80211_DEV(dev, &pdev->dev);
	pci_set_drvdata(pdev, dev);
	dev->extra_tx_headroom = sizeof(struct agnx_hdr);

	/* FIXME It only include FCS in promious mode but not manage mode */
/*      dev->flags =  IEEE80211_HW_RX_INCLUDES_FCS; */
	dev->channel_change_time = 5000;
	dev->max_signal = 100;
	/* FIXME */
	dev->queues = 1;

	agnx_get_mac_address(priv);

	SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);

/* 	/\* FIXME *\/ */
/* 	for (i = 1; i < NUM_DRIVE_MODES; i++) { */
/* 		err = ieee80211_register_hwmode(dev, &priv->modes[i]); */
/* 		if (err) { */
/* 			printk(KERN_ERR PFX "Can't register hwmode\n"); */
/* 			goto  err_iounmap; */
/* 		} */
/* 	} */

	priv->channel = 1;
	dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;

	err = ieee80211_register_hw(dev);
	if (err) {
		dev_err(&pdev->dev, "can't register hardware\n");
		goto err_iounmap;
	}

	agnx_hw_reset(priv);

	dev_info(&pdev->dev, "%s: hwaddr %pM, Rev 0x%02x\n",
		wiphy_name(dev->wiphy),
		dev->wiphy->perm_addr, priv->revid);
	return 0;

 err_iounmap:
	pci_iounmap(pdev, priv->data);

 err_iounmap2:
	pci_iounmap(pdev, priv->ctl);

 err_free_dev:
	pci_set_drvdata(pdev, NULL);
	ieee80211_free_hw(dev);

 err_free_reg:
	pci_release_regions(pdev);

	pci_disable_device(pdev);
	return err;
} /* agnx_pci_probe*/

#ifdef CONFIG_PM

static int agnx_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
	AGNX_TRACE;

	ieee80211_stop_queues(dev);
	agnx_stop(dev);

	pci_save_state(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
	return 0;
}

static int agnx_pci_resume(struct pci_dev *pdev)
{
	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
	AGNX_TRACE;

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);

	agnx_start(dev);
	ieee80211_wake_queues(dev);

	return 0;
}

#else

#define agnx_pci_suspend NULL
#define agnx_pci_resume NULL

#endif /* CONFIG_PM */


static struct pci_driver agnx_pci_driver = {
	.name		= "agnx-pci",
	.id_table	= agnx_pci_id_tbl,
	.probe		= agnx_pci_probe,
	.remove		= __devexit_p(agnx_pci_remove),
	.suspend	= agnx_pci_suspend,
	.resume		= agnx_pci_resume,
};

static int __init agnx_pci_init(void)
{
	AGNX_TRACE;
	return pci_register_driver(&agnx_pci_driver);
}

static void __exit agnx_pci_exit(void)
{
	AGNX_TRACE;
	pci_unregister_driver(&agnx_pci_driver);
}


module_init(agnx_pci_init);
module_exit(agnx_pci_exit);
