/*
 * SBE 2T3E3 synchronous serial card driver for Linux
 *
 * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 * This code is based on a driver written by SBE Inc.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/hdlc.h>
#include <linux/if_arp.h>
#include <linux/interrupt.h>
#include "2t3e3.h"

static void check_leds(unsigned long arg)
{
	struct card *card = (struct card *)arg;
	struct channel *channel0 = &card->channels[0];
	static int blinker;

	update_led(channel0, ++blinker);
	if (has_two_ports(channel0->pdev))
		update_led(&card->channels[1], blinker);

	card->timer.expires = jiffies + HZ / 10;
	add_timer(&card->timer);
}

static void t3e3_remove_channel(struct channel *channel)
{
	struct pci_dev *pdev = channel->pdev;
	struct net_device *dev = channel->dev;

	/* system hangs if board asserts irq while module is unloaded */
	cpld_stop_intr(channel);
	free_irq(dev->irq, dev);
	dc_drop_descriptor_list(channel);
	unregister_hdlc_device(dev);
	free_netdev(dev);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
}

static int t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
{
	struct net_device *dev;
	unsigned int val;
	int err;

	err = pci_enable_device(pdev);
	if (err)
		return err;

	err = pci_request_regions(pdev, "SBE 2T3E3");
	if (err)
		goto disable;

	dev = alloc_hdlcdev(channel);
	if (!dev) {
		pr_err("Out of memory\n");
		err = -ENOMEM;
		goto free_regions;
	}

	t3e3_sc_init(channel);
	dev_to_priv(dev) = channel;

	channel->pdev = pdev;
	channel->dev = dev;
	channel->card = card;
	channel->addr = pci_resource_start(pdev, 0);
	if (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)
		channel->h.slot = 1;
	else
		channel->h.slot = 0;

	err = setup_device(dev, channel);
	if (err)
		goto free_dev;

	pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */
	pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF);

	pci_read_config_byte(channel->pdev, PCI_CACHE_LINE_SIZE, &channel->h.cache_size);
	pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command);
	t3e3_init(channel);

	err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev);
	if (err) {
		netdev_warn(channel->dev, "%s: could not get irq: %d\n",
			    dev->name, dev->irq);
		goto unregister_dev;
	}

	pci_set_drvdata(pdev, channel);
	return 0;

unregister_dev:
	unregister_hdlc_device(dev);
free_dev:
	free_netdev(dev);
free_regions:
	pci_release_regions(pdev);
disable:
	pci_disable_device(pdev);
	return err;
}

static void t3e3_remove_card(struct pci_dev *pdev)
{
	struct channel *channel0 = pci_get_drvdata(pdev);
	struct card *card = channel0->card;

	del_timer_sync(&card->timer);
	if (has_two_ports(channel0->pdev)) {
		t3e3_remove_channel(&card->channels[1]);
		pci_dev_put(card->channels[1].pdev);
	}
	t3e3_remove_channel(channel0);
	kfree(card);
}

static int t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	/* pdev points to channel #0 */
	struct pci_dev *pdev1 = NULL;
	struct card *card;
	int channels = 1, err;

	if (has_two_ports(pdev)) {
		while ((pdev1 = pci_get_subsys(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
					       PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P1,
					       pdev1)))
			if (pdev1->bus == pdev->bus &&
			    pdev1->devfn == pdev->devfn + 8 /* next device on the same bus */)
				break; /* found the second channel */

		if (!pdev1) {
			dev_err(&pdev->dev, "Can't find the second channel\n");
			return -EFAULT;
		}
		channels = 2;
		/* holds the reference for pdev1 */
	}

	card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel),
		       GFP_KERNEL);
	if (!card)
		return -ENOBUFS;

	spin_lock_init(&card->bootrom_lock);
	card->bootrom_addr = pci_resource_start(pdev, 0);

	err = t3e3_init_channel(&card->channels[0], pdev, card);
	if (err)
		goto free_card;

	if (channels == 2) {
		err = t3e3_init_channel(&card->channels[1], pdev1, card);
		if (err) {
			t3e3_remove_channel(&card->channels[0]);
			goto free_card;
		}
	}

	/* start LED timer */
	init_timer(&card->timer);
	card->timer.function = check_leds;
	card->timer.expires = jiffies + HZ / 10;
	card->timer.data = (unsigned long)card;
	add_timer(&card->timer);
	return 0;

free_card:
	kfree(card);
	return err;
}

static struct pci_device_id t3e3_pci_tbl[] = {
	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
	  PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 },
	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
	  PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P0, 0, 0, 0 },
	/* channel 1 will be initialized after channel 0 */
	{ 0, }
};

static struct pci_driver t3e3_pci_driver = {
	.name     = "SBE T3E3",
	.id_table = t3e3_pci_tbl,
	.probe    = t3e3_init_card,
	.remove   = t3e3_remove_card,
};

module_pci_driver(t3e3_pci_driver);
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, t3e3_pci_tbl);
