cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

speedfax.c (12472B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * speedfax.c	low level stuff for Sedlbauer Speedfax+ cards
      4 *		based on the ISAR DSP
      5 *		Thanks to Sedlbauer AG for informations and HW
      6 *
      7 * Author       Karsten Keil <keil@isdn4linux.de>
      8 *
      9 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
     10 */
     11
     12#include <linux/interrupt.h>
     13#include <linux/module.h>
     14#include <linux/slab.h>
     15#include <linux/pci.h>
     16#include <linux/delay.h>
     17#include <linux/mISDNhw.h>
     18#include <linux/firmware.h>
     19#include "ipac.h"
     20#include "isar.h"
     21
     22#define SPEEDFAX_REV	"2.0"
     23
     24#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID	0x51
     25#define PCI_SUBVENDOR_SPEEDFAX_PCI	0x54
     26#define PCI_SUB_ID_SEDLBAUER		0x01
     27
     28#define SFAX_PCI_ADDR		0xc8
     29#define SFAX_PCI_ISAC		0xd0
     30#define SFAX_PCI_ISAR		0xe0
     31
     32/* TIGER 100 Registers */
     33
     34#define TIGER_RESET_ADDR	0x00
     35#define TIGER_EXTERN_RESET_ON	0x01
     36#define TIGER_EXTERN_RESET_OFF	0x00
     37#define TIGER_AUX_CTRL		0x02
     38#define TIGER_AUX_DATA		0x03
     39#define TIGER_AUX_IRQMASK	0x05
     40#define TIGER_AUX_STATUS	0x07
     41
     42/* Tiger AUX BITs */
     43#define SFAX_AUX_IOMASK		0xdd	/* 1 and 5 are inputs */
     44#define SFAX_ISAR_RESET_BIT_OFF 0x00
     45#define SFAX_ISAR_RESET_BIT_ON	0x01
     46#define SFAX_TIGER_IRQ_BIT	0x02
     47#define SFAX_LED1_BIT		0x08
     48#define SFAX_LED2_BIT		0x10
     49
     50#define SFAX_PCI_RESET_ON	(SFAX_ISAR_RESET_BIT_ON)
     51#define SFAX_PCI_RESET_OFF	(SFAX_LED1_BIT | SFAX_LED2_BIT)
     52
     53static int sfax_cnt;
     54static u32 debug;
     55static u32 irqloops = 4;
     56
     57struct sfax_hw {
     58	struct list_head	list;
     59	struct pci_dev		*pdev;
     60	char			name[MISDN_MAX_IDLEN];
     61	u32			irq;
     62	u32			irqcnt;
     63	u32			cfg;
     64	struct _ioport		p_isac;
     65	struct _ioport		p_isar;
     66	u8			aux_data;
     67	spinlock_t		lock;	/* HW access lock */
     68	struct isac_hw		isac;
     69	struct isar_hw		isar;
     70};
     71
     72static LIST_HEAD(Cards);
     73static DEFINE_RWLOCK(card_lock); /* protect Cards */
     74
     75static void
     76_set_debug(struct sfax_hw *card)
     77{
     78	card->isac.dch.debug = debug;
     79	card->isar.ch[0].bch.debug = debug;
     80	card->isar.ch[1].bch.debug = debug;
     81}
     82
     83static int
     84set_debug(const char *val, const struct kernel_param *kp)
     85{
     86	int ret;
     87	struct sfax_hw *card;
     88
     89	ret = param_set_uint(val, kp);
     90	if (!ret) {
     91		read_lock(&card_lock);
     92		list_for_each_entry(card, &Cards, list)
     93			_set_debug(card);
     94		read_unlock(&card_lock);
     95	}
     96	return ret;
     97}
     98
     99MODULE_AUTHOR("Karsten Keil");
    100MODULE_LICENSE("GPL v2");
    101MODULE_VERSION(SPEEDFAX_REV);
    102MODULE_FIRMWARE("isdn/ISAR.BIN");
    103module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
    104MODULE_PARM_DESC(debug, "Speedfax debug mask");
    105module_param(irqloops, uint, S_IRUGO | S_IWUSR);
    106MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
    107
    108IOFUNC_IND(ISAC, sfax_hw, p_isac)
    109IOFUNC_IND(ISAR, sfax_hw, p_isar)
    110
    111static irqreturn_t
    112speedfax_irq(int intno, void *dev_id)
    113{
    114	struct sfax_hw	*sf = dev_id;
    115	u8 val;
    116	int cnt = irqloops;
    117
    118	spin_lock(&sf->lock);
    119	val = inb(sf->cfg + TIGER_AUX_STATUS);
    120	if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
    121		spin_unlock(&sf->lock);
    122		return IRQ_NONE; /* shared */
    123	}
    124	sf->irqcnt++;
    125	val = ReadISAR_IND(sf, ISAR_IRQBIT);
    126Start_ISAR:
    127	if (val & ISAR_IRQSTA)
    128		mISDNisar_irq(&sf->isar);
    129	val = ReadISAC_IND(sf, ISAC_ISTA);
    130	if (val)
    131		mISDNisac_irq(&sf->isac, val);
    132	val = ReadISAR_IND(sf, ISAR_IRQBIT);
    133	if ((val & ISAR_IRQSTA) && cnt--)
    134		goto Start_ISAR;
    135	if (cnt < irqloops)
    136		pr_debug("%s: %d irqloops cpu%d\n", sf->name,
    137			 irqloops - cnt, smp_processor_id());
    138	if (irqloops && !cnt)
    139		pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
    140			  irqloops, smp_processor_id());
    141	spin_unlock(&sf->lock);
    142	return IRQ_HANDLED;
    143}
    144
    145static void
    146enable_hwirq(struct sfax_hw *sf)
    147{
    148	WriteISAC_IND(sf, ISAC_MASK, 0);
    149	WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
    150	outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
    151}
    152
    153static void
    154disable_hwirq(struct sfax_hw *sf)
    155{
    156	WriteISAC_IND(sf, ISAC_MASK, 0xFF);
    157	WriteISAR_IND(sf, ISAR_IRQBIT, 0);
    158	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
    159}
    160
    161static void
    162reset_speedfax(struct sfax_hw *sf)
    163{
    164
    165	pr_debug("%s: resetting card\n", sf->name);
    166	outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
    167	outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
    168	mdelay(1);
    169	outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
    170	sf->aux_data = SFAX_PCI_RESET_OFF;
    171	outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
    172	mdelay(1);
    173}
    174
    175static int
    176sfax_ctrl(struct sfax_hw  *sf, u32 cmd, u_long arg)
    177{
    178	int ret = 0;
    179
    180	switch (cmd) {
    181	case HW_RESET_REQ:
    182		reset_speedfax(sf);
    183		break;
    184	case HW_ACTIVATE_IND:
    185		if (arg & 1)
    186			sf->aux_data &= ~SFAX_LED1_BIT;
    187		if (arg & 2)
    188			sf->aux_data &= ~SFAX_LED2_BIT;
    189		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
    190		break;
    191	case HW_DEACT_IND:
    192		if (arg & 1)
    193			sf->aux_data |= SFAX_LED1_BIT;
    194		if (arg & 2)
    195			sf->aux_data |= SFAX_LED2_BIT;
    196		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
    197		break;
    198	default:
    199		pr_info("%s: %s unknown command %x %lx\n",
    200			sf->name, __func__, cmd, arg);
    201		ret = -EINVAL;
    202		break;
    203	}
    204	return ret;
    205}
    206
    207static int
    208channel_ctrl(struct sfax_hw  *sf, struct mISDN_ctrl_req *cq)
    209{
    210	int	ret = 0;
    211
    212	switch (cq->op) {
    213	case MISDN_CTRL_GETOP:
    214		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
    215		break;
    216	case MISDN_CTRL_LOOP:
    217		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
    218		if (cq->channel < 0 || cq->channel > 3) {
    219			ret = -EINVAL;
    220			break;
    221		}
    222		ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
    223		break;
    224	case MISDN_CTRL_L1_TIMER3:
    225		ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1);
    226		break;
    227	default:
    228		pr_info("%s: unknown Op %x\n", sf->name, cq->op);
    229		ret = -EINVAL;
    230		break;
    231	}
    232	return ret;
    233}
    234
    235static int
    236sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
    237{
    238	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
    239	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
    240	struct sfax_hw		*sf = dch->hw;
    241	struct channel_req	*rq;
    242	int			err = 0;
    243
    244	pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
    245	switch (cmd) {
    246	case OPEN_CHANNEL:
    247		rq = arg;
    248		if (rq->protocol == ISDN_P_TE_S0)
    249			err = sf->isac.open(&sf->isac, rq);
    250		else
    251			err = sf->isar.open(&sf->isar, rq);
    252		if (err)
    253			break;
    254		if (!try_module_get(THIS_MODULE))
    255			pr_info("%s: cannot get module\n", sf->name);
    256		break;
    257	case CLOSE_CHANNEL:
    258		pr_debug("%s: dev(%d) close from %p\n", sf->name,
    259			 dch->dev.id, __builtin_return_address(0));
    260		module_put(THIS_MODULE);
    261		break;
    262	case CONTROL_CHANNEL:
    263		err = channel_ctrl(sf, arg);
    264		break;
    265	default:
    266		pr_debug("%s: unknown command %x\n", sf->name, cmd);
    267		return -EINVAL;
    268	}
    269	return err;
    270}
    271
    272static int
    273init_card(struct sfax_hw *sf)
    274{
    275	int	ret, cnt = 3;
    276	u_long	flags;
    277
    278	ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
    279	if (ret) {
    280		pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
    281		return ret;
    282	}
    283	while (cnt--) {
    284		spin_lock_irqsave(&sf->lock, flags);
    285		ret = sf->isac.init(&sf->isac);
    286		if (ret) {
    287			spin_unlock_irqrestore(&sf->lock, flags);
    288			pr_info("%s: ISAC init failed with %d\n",
    289				sf->name, ret);
    290			break;
    291		}
    292		enable_hwirq(sf);
    293		/* RESET Receiver and Transmitter */
    294		WriteISAC_IND(sf, ISAC_CMDR, 0x41);
    295		spin_unlock_irqrestore(&sf->lock, flags);
    296		msleep_interruptible(10);
    297		if (debug & DEBUG_HW)
    298			pr_notice("%s: IRQ %d count %d\n", sf->name,
    299				  sf->irq, sf->irqcnt);
    300		if (!sf->irqcnt) {
    301			pr_info("%s: IRQ(%d) got no requests during init %d\n",
    302				sf->name, sf->irq, 3 - cnt);
    303		} else
    304			return 0;
    305	}
    306	free_irq(sf->irq, sf);
    307	return -EIO;
    308}
    309
    310
    311static int
    312setup_speedfax(struct sfax_hw *sf)
    313{
    314	u_long flags;
    315
    316	if (!request_region(sf->cfg, 256, sf->name)) {
    317		pr_info("mISDN: %s config port %x-%x already in use\n",
    318			sf->name, sf->cfg, sf->cfg + 255);
    319		return -EIO;
    320	}
    321	outb(0xff, sf->cfg);
    322	outb(0, sf->cfg);
    323	outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
    324	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
    325
    326	sf->isac.type = IPAC_TYPE_ISAC;
    327	sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
    328	sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
    329	sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
    330	sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
    331	ASSIGN_FUNC(IND, ISAC, sf->isac);
    332	ASSIGN_FUNC(IND, ISAR, sf->isar);
    333	spin_lock_irqsave(&sf->lock, flags);
    334	reset_speedfax(sf);
    335	disable_hwirq(sf);
    336	spin_unlock_irqrestore(&sf->lock, flags);
    337	return 0;
    338}
    339
    340static void
    341release_card(struct sfax_hw *card) {
    342	u_long	flags;
    343
    344	spin_lock_irqsave(&card->lock, flags);
    345	disable_hwirq(card);
    346	spin_unlock_irqrestore(&card->lock, flags);
    347	card->isac.release(&card->isac);
    348	free_irq(card->irq, card);
    349	card->isar.release(&card->isar);
    350	mISDN_unregister_device(&card->isac.dch.dev);
    351	release_region(card->cfg, 256);
    352	pci_disable_device(card->pdev);
    353	pci_set_drvdata(card->pdev, NULL);
    354	write_lock_irqsave(&card_lock, flags);
    355	list_del(&card->list);
    356	write_unlock_irqrestore(&card_lock, flags);
    357	kfree(card);
    358	sfax_cnt--;
    359}
    360
    361static int
    362setup_instance(struct sfax_hw *card)
    363{
    364	const struct firmware *firmware;
    365	int i, err;
    366	u_long flags;
    367
    368	snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
    369	write_lock_irqsave(&card_lock, flags);
    370	list_add_tail(&card->list, &Cards);
    371	write_unlock_irqrestore(&card_lock, flags);
    372	_set_debug(card);
    373	spin_lock_init(&card->lock);
    374	card->isac.hwlock = &card->lock;
    375	card->isar.hwlock = &card->lock;
    376	card->isar.ctrl = (void *)&sfax_ctrl;
    377	card->isac.name = card->name;
    378	card->isar.name = card->name;
    379	card->isar.owner = THIS_MODULE;
    380
    381	err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
    382	if (err < 0) {
    383		pr_info("%s: firmware request failed %d\n",
    384			card->name, err);
    385		goto error_fw;
    386	}
    387	if (debug & DEBUG_HW)
    388		pr_notice("%s: got firmware %zu bytes\n",
    389			  card->name, firmware->size);
    390
    391	mISDNisac_init(&card->isac, card);
    392
    393	card->isac.dch.dev.D.ctrl = sfax_dctrl;
    394	card->isac.dch.dev.Bprotocols =
    395		mISDNisar_init(&card->isar, card);
    396	for (i = 0; i < 2; i++) {
    397		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
    398		list_add(&card->isar.ch[i].bch.ch.list,
    399			 &card->isac.dch.dev.bchannels);
    400	}
    401
    402	err = setup_speedfax(card);
    403	if (err)
    404		goto error_setup;
    405	err = card->isar.init(&card->isar);
    406	if (err)
    407		goto error;
    408	err = mISDN_register_device(&card->isac.dch.dev,
    409				    &card->pdev->dev, card->name);
    410	if (err)
    411		goto error;
    412	err = init_card(card);
    413	if (err)
    414		goto error_init;
    415	err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
    416	if (!err)  {
    417		release_firmware(firmware);
    418		sfax_cnt++;
    419		pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
    420		return 0;
    421	}
    422	disable_hwirq(card);
    423	free_irq(card->irq, card);
    424error_init:
    425	mISDN_unregister_device(&card->isac.dch.dev);
    426error:
    427	release_region(card->cfg, 256);
    428error_setup:
    429	card->isac.release(&card->isac);
    430	card->isar.release(&card->isar);
    431	release_firmware(firmware);
    432error_fw:
    433	pci_disable_device(card->pdev);
    434	write_lock_irqsave(&card_lock, flags);
    435	list_del(&card->list);
    436	write_unlock_irqrestore(&card_lock, flags);
    437	kfree(card);
    438	return err;
    439}
    440
    441static int
    442sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
    443{
    444	int err = -ENOMEM;
    445	struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);
    446
    447	if (!card) {
    448		pr_info("No memory for Speedfax+ PCI\n");
    449		return err;
    450	}
    451	card->pdev = pdev;
    452	err = pci_enable_device(pdev);
    453	if (err) {
    454		kfree(card);
    455		return err;
    456	}
    457
    458	pr_notice("mISDN: Speedfax found adapter %s at %s\n",
    459		  (char *)ent->driver_data, pci_name(pdev));
    460
    461	card->cfg = pci_resource_start(pdev, 0);
    462	card->irq = pdev->irq;
    463	pci_set_drvdata(pdev, card);
    464	err = setup_instance(card);
    465	if (err)
    466		pci_set_drvdata(pdev, NULL);
    467	return err;
    468}
    469
    470static void
    471sfax_remove_pci(struct pci_dev *pdev)
    472{
    473	struct sfax_hw	*card = pci_get_drvdata(pdev);
    474
    475	if (card)
    476		release_card(card);
    477	else
    478		pr_debug("%s: drvdata already removed\n", __func__);
    479}
    480
    481static struct pci_device_id sfaxpci_ids[] = {
    482	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
    483	  PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
    484	  0, 0, (unsigned long) "Pyramid Speedfax + PCI"
    485	},
    486	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
    487	  PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
    488	  0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
    489	},
    490	{ }
    491};
    492MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
    493
    494static struct pci_driver sfaxpci_driver = {
    495	.name = "speedfax+ pci",
    496	.probe = sfaxpci_probe,
    497	.remove = sfax_remove_pci,
    498	.id_table = sfaxpci_ids,
    499};
    500
    501static int __init
    502Speedfax_init(void)
    503{
    504	int err;
    505
    506	pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
    507		  SPEEDFAX_REV);
    508	err = pci_register_driver(&sfaxpci_driver);
    509	return err;
    510}
    511
    512static void __exit
    513Speedfax_cleanup(void)
    514{
    515	pci_unregister_driver(&sfaxpci_driver);
    516}
    517
    518module_init(Speedfax_init);
    519module_exit(Speedfax_cleanup);