/* orinoco_nortel.c
 * 
 * Driver for Prism II devices which would usually be driven by orinoco_cs,
 * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter. 
 *
 * Copyright (C) 2002 Tobias Hoffmann
 *           (C) 2003 Christoph Jungegger <disdos@traum404.de>
 *
 * Some of this code is borrowed from orinoco_plx.c
 *	Copyright (C) 2001 Daniel Barlow
 * Some of this code is borrowed from orinoco_pci.c 
 *  Copyright (C) 2001 Jean Tourrilhes
 * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
 * has been copied from it. linux-wlan-ng-0.1.10 is originally :
 *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
 * 
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License
 * at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and
 * limitations under the License.
 *
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License version 2 (the "GPL"), in
 * which case the provisions of the GPL are applicable instead of the
 * above.  If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use your
 * version of this file under the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice and
 * other provisions required by the GPL.  If you do not delete the
 * provisions above, a recipient may use your version of this file
 * under either the MPL or the GPL.
 */

#define DRIVER_NAME "orinoco_nortel"
#define PFX DRIVER_NAME ": "

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <pcmcia/cisreg.h>

#include "orinoco.h"

#define COR_OFFSET    (0xe0)	/* COR attribute offset of Prism2 PC card */
#define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA)	/* Enable PC card with interrupt in level trigger */


/* Nortel specific data */
struct nortel_pci_card {
	unsigned long iobase1;
	unsigned long iobase2;
};

/*
 * Do a soft reset of the PCI card using the Configuration Option Register
 * We need this to get going...
 * This is the part of the code that is strongly inspired from wlan-ng
 *
 * Note bis : Don't try to access HERMES_CMD during the reset phase.
 * It just won't work !
 */
static int nortel_pci_cor_reset(struct orinoco_private *priv)
{
	struct nortel_pci_card *card = priv->card;

	/* Assert the reset until the card notice */
	outw_p(8, card->iobase1 + 2);
	inw(card->iobase2 + COR_OFFSET);
	outw_p(0x80, card->iobase2 + COR_OFFSET);
	mdelay(1);

	/* Give time for the card to recover from this hard effort */
	outw_p(0, card->iobase2 + COR_OFFSET);
	outw_p(0, card->iobase2 + COR_OFFSET);
	mdelay(1);

	/* set COR as usual */
	outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
	outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
	mdelay(1);

	outw_p(0x228, card->iobase1 + 2);

	return 0;
}

static int nortel_pci_hw_init(struct nortel_pci_card *card)
{
	int i;
	u32 reg;

	/* setup bridge */
	if (inw(card->iobase1) & 1) {
		printk(KERN_ERR PFX "brg1 answer1 wrong\n");
		return -EBUSY;
	}
	outw_p(0x118, card->iobase1 + 2);
	outw_p(0x108, card->iobase1 + 2);
	mdelay(30);
	outw_p(0x8, card->iobase1 + 2);
	for (i = 0; i < 30; i++) {
		mdelay(30);
		if (inw(card->iobase1) & 0x10) {
			break;
		}
	}
	if (i == 30) {
		printk(KERN_ERR PFX "brg1 timed out\n");
		return -EBUSY;
	}
	if (inw(card->iobase2 + 0xe0) & 1) {
		printk(KERN_ERR PFX "brg2 answer1 wrong\n");
		return -EBUSY;
	}
	if (inw(card->iobase2 + 0xe2) & 1) {
		printk(KERN_ERR PFX "brg2 answer2 wrong\n");
		return -EBUSY;
	}
	if (inw(card->iobase2 + 0xe4) & 1) {
		printk(KERN_ERR PFX "brg2 answer3 wrong\n");
		return -EBUSY;
	}

	/* set the PCMCIA COR-Register */
	outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
	mdelay(1);
	reg = inw(card->iobase2 + COR_OFFSET);
	if (reg != COR_VALUE) {
		printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
		       reg);
		return -EBUSY;
	}

	/* set leds */
	outw_p(1, card->iobase1 + 10);
	return 0;
}

static int nortel_pci_init_one(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	int err;
	struct orinoco_private *priv;
	struct nortel_pci_card *card;
	struct net_device *dev;
	void __iomem *iomem;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err != 0) {
		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
		goto fail_resources;
	}

	iomem = pci_iomap(pdev, 3, 0);
	if (!iomem) {
		err = -ENOMEM;
		goto fail_map_io;
	}

	/* Allocate network device */
	dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset);
	if (!dev) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		err = -ENOMEM;
		goto fail_alloc;
	}

	priv = netdev_priv(dev);
	card = priv->card;
	card->iobase1 = pci_resource_start(pdev, 0);
	card->iobase2 = pci_resource_start(pdev, 1);
	dev->base_addr = pci_resource_start(pdev, 2);
	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING);

	printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, "
	       "io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
			  dev->name, dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
		err = -EBUSY;
		goto fail_irq;
	}
	dev->irq = pdev->irq;

	err = nortel_pci_hw_init(card);
	if (err) {
		printk(KERN_ERR PFX "Hardware initialization failed\n");
		goto fail;
	}

	err = nortel_pci_cor_reset(priv);
	if (err) {
		printk(KERN_ERR PFX "Initial reset failed\n");
		goto fail;
	}


	err = register_netdev(dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot register network device\n");
		goto fail;
	}

	pci_set_drvdata(pdev, dev);

	return 0;

 fail:
	free_irq(pdev->irq, dev);

 fail_irq:
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(dev);

 fail_alloc:
	pci_iounmap(pdev, iomem);

 fail_map_io:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}

static void __devexit nortel_pci_remove_one(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);
	struct orinoco_private *priv = netdev_priv(dev);
	struct nortel_pci_card *card = priv->card;

	/* clear leds */
	outw_p(0, card->iobase1 + 10);

	unregister_netdev(dev);
	free_irq(dev->irq, dev);
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(dev);
	pci_iounmap(pdev, priv->hw.iobase);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
}


static struct pci_device_id nortel_pci_id_table[] = {
	/* Nortel emobility PCI */
	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
	{0,},
};

MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);

static struct pci_driver nortel_pci_driver = {
	.name = DRIVER_NAME,
	.id_table = nortel_pci_id_table,
	.probe = nortel_pci_init_one,
	.remove = __devexit_p(nortel_pci_remove_one),
};

static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
	" (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
MODULE_DESCRIPTION
    ("Driver for wireless LAN cards using the Nortel PCI bridge");
MODULE_LICENSE("Dual MPL/GPL");

static int __init nortel_pci_init(void)
{
	printk(KERN_DEBUG "%s\n", version);
	return pci_module_init(&nortel_pci_driver);
}

static void __exit nortel_pci_exit(void)
{
	pci_unregister_driver(&nortel_pci_driver);
	ssleep(1);
}

module_init(nortel_pci_init);
module_exit(nortel_pci_exit);

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 *  tab-width: 8
 * End:
 */
