File Index
Files and directories
Sign in
FILE

avmfritz.c

File preview with syntax highlighting.

linux-6.19.14/drivers/isdn/hardware/mISDN/avmfritz.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * avm_fritz.c    low level stuff for AVM FRITZ!CARD PCI ISDN cards
   4 *                Thanks to AVM, Berlin for informations
   5 *
   6 * Author       Karsten Keil <keil@isdn4linux.de>
   7 *
   8 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
   9 */
  10#include <linux/interrupt.h>
  11#include <linux/module.h>
  12#include <linux/pci.h>
  13#include <linux/delay.h>
  14#include <linux/mISDNhw.h>
  15#include <linux/slab.h>
  16#include <linux/unaligned.h>
  17#include "ipac.h"
  18
  19
  20#define AVMFRITZ_REV	"2.3"
  21
  22static int AVM_cnt;
  23static int debug;
  24
  25enum {
  26	AVM_FRITZ_PCI,
  27	AVM_FRITZ_PCIV2,
  28};
  29
  30#define HDLC_FIFO		0x0
  31#define HDLC_STATUS		0x4
  32#define CHIP_WINDOW		0x10
  33
  34#define CHIP_INDEX		0x4
  35#define AVM_HDLC_1		0x00
  36#define AVM_HDLC_2		0x01
  37#define AVM_ISAC_FIFO		0x02
  38#define AVM_ISAC_REG_LOW	0x04
  39#define AVM_ISAC_REG_HIGH	0x06
  40
  41#define AVM_STATUS0_IRQ_ISAC	0x01
  42#define AVM_STATUS0_IRQ_HDLC	0x02
  43#define AVM_STATUS0_IRQ_TIMER	0x04
  44#define AVM_STATUS0_IRQ_MASK	0x07
  45
  46#define AVM_STATUS0_RESET	0x01
  47#define AVM_STATUS0_DIS_TIMER	0x02
  48#define AVM_STATUS0_RES_TIMER	0x04
  49#define AVM_STATUS0_ENA_IRQ	0x08
  50#define AVM_STATUS0_TESTBIT	0x10
  51
  52#define AVM_STATUS1_INT_SEL	0x0f
  53#define AVM_STATUS1_ENA_IOM	0x80
  54
  55#define HDLC_MODE_ITF_FLG	0x01
  56#define HDLC_MODE_TRANS		0x02
  57#define HDLC_MODE_CCR_7		0x04
  58#define HDLC_MODE_CCR_16	0x08
  59#define HDLC_FIFO_SIZE_128	0x20
  60#define HDLC_MODE_TESTLOOP	0x80
  61
  62#define HDLC_INT_XPR		0x80
  63#define HDLC_INT_XDU		0x40
  64#define HDLC_INT_RPR		0x20
  65#define HDLC_INT_MASK		0xE0
  66
  67#define HDLC_STAT_RME		0x01
  68#define HDLC_STAT_RDO		0x10
  69#define HDLC_STAT_CRCVFRRAB	0x0E
  70#define HDLC_STAT_CRCVFR	0x06
  71#define HDLC_STAT_RML_MASK_V1	0x3f00
  72#define HDLC_STAT_RML_MASK_V2	0x7f00
  73
  74#define HDLC_CMD_XRS		0x80
  75#define HDLC_CMD_XME		0x01
  76#define HDLC_CMD_RRS		0x20
  77#define HDLC_CMD_XML_MASK	0x3f00
  78
  79#define HDLC_FIFO_SIZE_V1	32
  80#define HDLC_FIFO_SIZE_V2	128
  81
  82/* Fritz PCI v2.0 */
  83
  84#define AVM_HDLC_FIFO_1		0x10
  85#define AVM_HDLC_FIFO_2		0x18
  86
  87#define AVM_HDLC_STATUS_1	0x14
  88#define AVM_HDLC_STATUS_2	0x1c
  89
  90#define AVM_ISACX_INDEX		0x04
  91#define AVM_ISACX_DATA		0x08
  92
  93/* data struct */
  94#define LOG_SIZE		63
  95
  96struct hdlc_stat_reg {
  97#ifdef __BIG_ENDIAN
  98	u8 fill;
  99	u8 mode;
 100	u8 xml;
 101	u8 cmd;
 102#else
 103	u8 cmd;
 104	u8 xml;
 105	u8 mode;
 106	u8 fill;
 107#endif
 108} __attribute__((packed));
 109
 110struct hdlc_hw {
 111	union {
 112		u32 ctrl;
 113		struct hdlc_stat_reg sr;
 114	} ctrl;
 115	u32 stat;
 116};
 117
 118struct fritzcard {
 119	struct list_head	list;
 120	struct pci_dev		*pdev;
 121	char			name[MISDN_MAX_IDLEN];
 122	u8			type;
 123	u8			ctrlreg;
 124	u16			irq;
 125	u32			irqcnt;
 126	u32			addr;
 127	spinlock_t		lock; /* hw lock */
 128	struct isac_hw		isac;
 129	struct hdlc_hw		hdlc[2];
 130	struct bchannel		bch[2];
 131	char			log[LOG_SIZE + 1];
 132};
 133
 134static LIST_HEAD(Cards);
 135static DEFINE_RWLOCK(card_lock); /* protect Cards */
 136
 137static void
 138_set_debug(struct fritzcard *card)
 139{
 140	card->isac.dch.debug = debug;
 141	card->bch[0].debug = debug;
 142	card->bch[1].debug = debug;
 143}
 144
 145static int
 146set_debug(const char *val, const struct kernel_param *kp)
 147{
 148	int ret;
 149	struct fritzcard *card;
 150
 151	ret = param_set_uint(val, kp);
 152	if (!ret) {
 153		read_lock(&card_lock);
 154		list_for_each_entry(card, &Cards, list)
 155			_set_debug(card);
 156		read_unlock(&card_lock);
 157	}
 158	return ret;
 159}
 160
 161MODULE_AUTHOR("Karsten Keil");
 162MODULE_DESCRIPTION("mISDN driver for AVM FRITZ!CARD PCI ISDN cards");
 163MODULE_LICENSE("GPL v2");
 164MODULE_VERSION(AVMFRITZ_REV);
 165module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
 166MODULE_PARM_DESC(debug, "avmfritz debug mask");
 167
 168/* Interface functions */
 169
 170static u8
 171ReadISAC_V1(void *p, u8 offset)
 172{
 173	struct fritzcard *fc = p;
 174	u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
 175
 176	outb(idx, fc->addr + CHIP_INDEX);
 177	return inb(fc->addr + CHIP_WINDOW + (offset & 0xf));
 178}
 179
 180static void
 181WriteISAC_V1(void *p, u8 offset, u8 value)
 182{
 183	struct fritzcard *fc = p;
 184	u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
 185
 186	outb(idx, fc->addr + CHIP_INDEX);
 187	outb(value, fc->addr + CHIP_WINDOW + (offset & 0xf));
 188}
 189
 190static void
 191ReadFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
 192{
 193	struct fritzcard *fc = p;
 194
 195	outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
 196	insb(fc->addr + CHIP_WINDOW, data, size);
 197}
 198
 199static void
 200WriteFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
 201{
 202	struct fritzcard *fc = p;
 203
 204	outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
 205	outsb(fc->addr + CHIP_WINDOW, data, size);
 206}
 207
 208static u8
 209ReadISAC_V2(void *p, u8 offset)
 210{
 211	struct fritzcard *fc = p;
 212
 213	outl(offset, fc->addr + AVM_ISACX_INDEX);
 214	return 0xff & inl(fc->addr + AVM_ISACX_DATA);
 215}
 216
 217static void
 218WriteISAC_V2(void *p, u8 offset, u8 value)
 219{
 220	struct fritzcard *fc = p;
 221
 222	outl(offset, fc->addr + AVM_ISACX_INDEX);
 223	outl(value, fc->addr + AVM_ISACX_DATA);
 224}
 225
 226static void
 227ReadFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
 228{
 229	struct fritzcard *fc = p;
 230	int i;
 231
 232	outl(off, fc->addr + AVM_ISACX_INDEX);
 233	for (i = 0; i < size; i++)
 234		data[i] = 0xff & inl(fc->addr + AVM_ISACX_DATA);
 235}
 236
 237static void
 238WriteFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
 239{
 240	struct fritzcard *fc = p;
 241	int i;
 242
 243	outl(off, fc->addr + AVM_ISACX_INDEX);
 244	for (i = 0; i < size; i++)
 245		outl(data[i], fc->addr + AVM_ISACX_DATA);
 246}
 247
 248static struct bchannel *
 249Sel_BCS(struct fritzcard *fc, u32 channel)
 250{
 251	if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) &&
 252	    (fc->bch[0].nr & channel))
 253		return &fc->bch[0];
 254	else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) &&
 255		 (fc->bch[1].nr & channel))
 256		return &fc->bch[1];
 257	else
 258		return NULL;
 259}
 260
 261static inline void
 262__write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
 263	u32 idx = channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1;
 264
 265	outl(idx, fc->addr + CHIP_INDEX);
 266	outl(hdlc->ctrl.ctrl, fc->addr + CHIP_WINDOW + HDLC_STATUS);
 267}
 268
 269static inline void
 270__write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
 271	outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
 272					  AVM_HDLC_STATUS_1));
 273}
 274
 275static void
 276write_ctrl(struct bchannel *bch, int which) {
 277	struct fritzcard *fc = bch->hw;
 278	struct hdlc_hw *hdlc;
 279
 280	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
 281	pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr,
 282		 which, hdlc->ctrl.ctrl);
 283	switch (fc->type) {
 284	case AVM_FRITZ_PCIV2:
 285		__write_ctrl_pciv2(fc, hdlc, bch->nr);
 286		break;
 287	case AVM_FRITZ_PCI:
 288		__write_ctrl_pci(fc, hdlc, bch->nr);
 289		break;
 290	}
 291}
 292
 293
 294static inline u32
 295__read_status_pci(u_long addr, u32 channel)
 296{
 297	outl(channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1, addr + CHIP_INDEX);
 298	return inl(addr + CHIP_WINDOW + HDLC_STATUS);
 299}
 300
 301static inline u32
 302__read_status_pciv2(u_long addr, u32 channel)
 303{
 304	return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
 305			   AVM_HDLC_STATUS_1));
 306}
 307
 308
 309static u32
 310read_status(struct fritzcard *fc, u32 channel)
 311{
 312	switch (fc->type) {
 313	case AVM_FRITZ_PCIV2:
 314		return __read_status_pciv2(fc->addr, channel);
 315	case AVM_FRITZ_PCI:
 316		return __read_status_pci(fc->addr, channel);
 317	}
 318	/* dummy */
 319	return 0;
 320}
 321
 322static void
 323enable_hwirq(struct fritzcard *fc)
 324{
 325	fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
 326	outb(fc->ctrlreg, fc->addr + 2);
 327}
 328
 329static void
 330disable_hwirq(struct fritzcard *fc)
 331{
 332	fc->ctrlreg &= ~AVM_STATUS0_ENA_IRQ;
 333	outb(fc->ctrlreg, fc->addr + 2);
 334}
 335
 336static int
 337modehdlc(struct bchannel *bch, int protocol)
 338{
 339	struct fritzcard *fc = bch->hw;
 340	struct hdlc_hw *hdlc;
 341	u8 mode;
 342
 343	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
 344	pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name,
 345		 '@' + bch->nr, bch->state, protocol, bch->nr);
 346	hdlc->ctrl.ctrl = 0;
 347	mode = (fc->type == AVM_FRITZ_PCIV2) ? HDLC_FIFO_SIZE_128 : 0;
 348
 349	switch (protocol) {
 350	case -1: /* used for init */
 351		bch->state = -1;
 352		fallthrough;
 353	case ISDN_P_NONE:
 354		if (bch->state == ISDN_P_NONE)
 355			break;
 356		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
 357		hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS;
 358		write_ctrl(bch, 5);
 359		bch->state = ISDN_P_NONE;
 360		test_and_clear_bit(FLG_HDLC, &bch->Flags);
 361		test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
 362		break;
 363	case ISDN_P_B_RAW:
 364		bch->state = protocol;
 365		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
 366		hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS;
 367		write_ctrl(bch, 5);
 368		hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
 369		write_ctrl(bch, 1);
 370		hdlc->ctrl.sr.cmd = 0;
 371		test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
 372		break;
 373	case ISDN_P_B_HDLC:
 374		bch->state = protocol;
 375		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
 376		hdlc->ctrl.sr.mode = mode | HDLC_MODE_ITF_FLG;
 377		write_ctrl(bch, 5);
 378		hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
 379		write_ctrl(bch, 1);
 380		hdlc->ctrl.sr.cmd = 0;
 381		test_and_set_bit(FLG_HDLC, &bch->Flags);
 382		break;
 383	default:
 384		pr_info("%s: protocol not known %x\n", fc->name, protocol);
 385		return -ENOPROTOOPT;
 386	}
 387	return 0;
 388}
 389
 390static void
 391hdlc_empty_fifo(struct bchannel *bch, int count)
 392{
 393	u32 *ptr;
 394	u8 *p;
 395	u32  val, addr;
 396	int cnt;
 397	struct fritzcard *fc = bch->hw;
 398
 399	pr_debug("%s: %s %d\n", fc->name, __func__, count);
 400	if (test_bit(FLG_RX_OFF, &bch->Flags)) {
 401		p = NULL;
 402		bch->dropcnt += count;
 403	} else {
 404		cnt = bchannel_get_rxbuf(bch, count);
 405		if (cnt < 0) {
 406			pr_warn("%s.B%d: No bufferspace for %d bytes\n",
 407				fc->name, bch->nr, count);
 408			return;
 409		}
 410		p = skb_put(bch->rx_skb, count);
 411	}
 412	ptr = (u32 *)p;
 413	if (fc->type == AVM_FRITZ_PCIV2)
 414		addr = fc->addr + (bch->nr == 2 ?
 415				   AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
 416	else {
 417		addr = fc->addr + CHIP_WINDOW;
 418		outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr);
 419	}
 420	cnt = 0;
 421	while (cnt < count) {
 422		val = le32_to_cpu(inl(addr));
 423		if (p) {
 424			put_unaligned(val, ptr);
 425			ptr++;
 426		}
 427		cnt += 4;
 428	}
 429	if (p && (debug & DEBUG_HW_BFIFO)) {
 430		snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
 431			 bch->nr, fc->name, count);
 432		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
 433	}
 434}
 435
 436static void
 437hdlc_fill_fifo(struct bchannel *bch)
 438{
 439	struct fritzcard *fc = bch->hw;
 440	struct hdlc_hw *hdlc;
 441	int count, fs, cnt = 0, idx;
 442	bool fillempty = false;
 443	u8 *p;
 444	u32 *ptr, val, addr;
 445
 446	idx = (bch->nr - 1) & 1;
 447	hdlc = &fc->hdlc[idx];
 448	fs = (fc->type == AVM_FRITZ_PCIV2) ?
 449		HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1;
 450	if (!bch->tx_skb) {
 451		if (!test_bit(FLG_TX_EMPTY, &bch->Flags))
 452			return;
 453		count = fs;
 454		p = bch->fill;
 455		fillempty = true;
 456	} else {
 457		count = bch->tx_skb->len - bch->tx_idx;
 458		if (count <= 0)
 459			return;
 460		p = bch->tx_skb->data + bch->tx_idx;
 461	}
 462	hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
 463	if (count > fs) {
 464		count = fs;
 465	} else {
 466		if (test_bit(FLG_HDLC, &bch->Flags))
 467			hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
 468	}
 469	ptr = (u32 *)p;
 470	if (!fillempty) {
 471		pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count,
 472			 bch->tx_idx, bch->tx_skb->len);
 473		bch->tx_idx += count;
 474	} else {
 475		pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count);
 476	}
 477	hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count);
 478	if (fc->type == AVM_FRITZ_PCIV2) {
 479		__write_ctrl_pciv2(fc, hdlc, bch->nr);
 480		addr = fc->addr + (bch->nr == 2 ?
 481				   AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
 482	} else {
 483		__write_ctrl_pci(fc, hdlc, bch->nr);
 484		addr = fc->addr + CHIP_WINDOW;
 485	}
 486	if (fillempty) {
 487		while (cnt < count) {
 488			/* all bytes the same - no worry about endian */
 489			outl(*ptr, addr);
 490			cnt += 4;
 491		}
 492	} else {
 493		while (cnt < count) {
 494			val = get_unaligned(ptr);
 495			outl(cpu_to_le32(val), addr);
 496			ptr++;
 497			cnt += 4;
 498		}
 499	}
 500	if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
 501		snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
 502			 bch->nr, fc->name, count);
 503		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
 504	}
 505}
 506
 507static void
 508HDLC_irq_xpr(struct bchannel *bch)
 509{
 510	if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) {
 511		hdlc_fill_fifo(bch);
 512	} else {
 513		dev_kfree_skb(bch->tx_skb);
 514		if (get_next_bframe(bch)) {
 515			hdlc_fill_fifo(bch);
 516			test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags);
 517		} else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) {
 518			hdlc_fill_fifo(bch);
 519		}
 520	}
 521}
 522
 523static void
 524HDLC_irq(struct bchannel *bch, u32 stat)
 525{
 526	struct fritzcard *fc = bch->hw;
 527	int		len, fs;
 528	u32		rmlMask;
 529	struct hdlc_hw	*hdlc;
 530
 531	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
 532	pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat);
 533	if (fc->type == AVM_FRITZ_PCIV2) {
 534		rmlMask = HDLC_STAT_RML_MASK_V2;
 535		fs = HDLC_FIFO_SIZE_V2;
 536	} else {
 537		rmlMask = HDLC_STAT_RML_MASK_V1;
 538		fs = HDLC_FIFO_SIZE_V1;
 539	}
 540	if (stat & HDLC_INT_RPR) {
 541		if (stat & HDLC_STAT_RDO) {
 542			pr_warn("%s: ch%d stat %x RDO\n",
 543				fc->name, bch->nr, stat);
 544			hdlc->ctrl.sr.xml = 0;
 545			hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS;
 546			write_ctrl(bch, 1);
 547			hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
 548			write_ctrl(bch, 1);
 549			if (bch->rx_skb)
 550				skb_trim(bch->rx_skb, 0);
 551		} else {
 552			len = (stat & rmlMask) >> 8;
 553			if (!len)
 554				len = fs;
 555			hdlc_empty_fifo(bch, len);
 556			if (!bch->rx_skb)
 557				goto handle_tx;
 558			if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
 559				recv_Bchannel(bch, 0, false);
 560			} else if (stat & HDLC_STAT_RME) {
 561				if ((stat & HDLC_STAT_CRCVFRRAB) ==
 562				    HDLC_STAT_CRCVFR) {
 563					recv_Bchannel(bch, 0, false);
 564				} else {
 565					pr_warn("%s: got invalid frame\n",
 566						fc->name);
 567					skb_trim(bch->rx_skb, 0);
 568				}
 569			}
 570		}
 571	}
 572handle_tx:
 573	if (stat & HDLC_INT_XDU) {
 574		/* Here we lost an TX interrupt, so
 575		 * restart transmitting the whole frame on HDLC
 576		 * in transparent mode we send the next data
 577		 */
 578		pr_warn("%s: ch%d stat %x XDU %s\n", fc->name, bch->nr,
 579			stat, bch->tx_skb ? "tx_skb" : "no tx_skb");
 580		if (bch->tx_skb && bch->tx_skb->len) {
 581			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
 582				bch->tx_idx = 0;
 583		} else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
 584			test_and_set_bit(FLG_TX_EMPTY, &bch->Flags);
 585		}
 586		hdlc->ctrl.sr.xml = 0;
 587		hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS;
 588		write_ctrl(bch, 1);
 589		hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
 590		HDLC_irq_xpr(bch);
 591		return;
 592	} else if (stat & HDLC_INT_XPR)
 593		HDLC_irq_xpr(bch);
 594}
 595
 596static inline void
 597HDLC_irq_main(struct fritzcard *fc)
 598{
 599	u32 stat;
 600	struct bchannel *bch;
 601
 602	stat = read_status(fc, 1);
 603	if (stat & HDLC_INT_MASK) {
 604		bch = Sel_BCS(fc, 1);
 605		if (bch)
 606			HDLC_irq(bch, stat);
 607		else
 608			pr_debug("%s: spurious ch1 IRQ\n", fc->name);
 609	}
 610	stat = read_status(fc, 2);
 611	if (stat & HDLC_INT_MASK) {
 612		bch = Sel_BCS(fc, 2);
 613		if (bch)
 614			HDLC_irq(bch, stat);
 615		else
 616			pr_debug("%s: spurious ch2 IRQ\n", fc->name);
 617	}
 618}
 619
 620static irqreturn_t
 621avm_fritz_interrupt(int intno, void *dev_id)
 622{
 623	struct fritzcard *fc = dev_id;
 624	u8 val;
 625	u8 sval;
 626
 627	spin_lock(&fc->lock);
 628	sval = inb(fc->addr + 2);
 629	pr_debug("%s: irq stat0 %x\n", fc->name, sval);
 630	if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
 631		/* shared  IRQ from other HW */
 632		spin_unlock(&fc->lock);
 633		return IRQ_NONE;
 634	}
 635	fc->irqcnt++;
 636
 637	if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
 638		val = ReadISAC_V1(fc, ISAC_ISTA);
 639		mISDNisac_irq(&fc->isac, val);
 640	}
 641	if (!(sval & AVM_STATUS0_IRQ_HDLC))
 642		HDLC_irq_main(fc);
 643	spin_unlock(&fc->lock);
 644	return IRQ_HANDLED;
 645}
 646
 647static irqreturn_t
 648avm_fritzv2_interrupt(int intno, void *dev_id)
 649{
 650	struct fritzcard *fc = dev_id;
 651	u8 val;
 652	u8 sval;
 653
 654	spin_lock(&fc->lock);
 655	sval = inb(fc->addr + 2);
 656	pr_debug("%s: irq stat0 %x\n", fc->name, sval);
 657	if (!(sval & AVM_STATUS0_IRQ_MASK)) {
 658		/* shared  IRQ from other HW */
 659		spin_unlock(&fc->lock);
 660		return IRQ_NONE;
 661	}
 662	fc->irqcnt++;
 663
 664	if (sval & AVM_STATUS0_IRQ_HDLC)
 665		HDLC_irq_main(fc);
 666	if (sval & AVM_STATUS0_IRQ_ISAC) {
 667		val = ReadISAC_V2(fc, ISACX_ISTA);
 668		mISDNisac_irq(&fc->isac, val);
 669	}
 670	if (sval & AVM_STATUS0_IRQ_TIMER) {
 671		pr_debug("%s: timer irq\n", fc->name);
 672		outb(fc->ctrlreg | AVM_STATUS0_RES_TIMER, fc->addr + 2);
 673		udelay(1);
 674		outb(fc->ctrlreg, fc->addr + 2);
 675	}
 676	spin_unlock(&fc->lock);
 677	return IRQ_HANDLED;
 678}
 679
 680static int
 681avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 682{
 683	struct bchannel *bch = container_of(ch, struct bchannel, ch);
 684	struct fritzcard *fc = bch->hw;
 685	int ret = -EINVAL;
 686	struct mISDNhead *hh = mISDN_HEAD_P(skb);
 687	unsigned long flags;
 688
 689	switch (hh->prim) {
 690	case PH_DATA_REQ:
 691		spin_lock_irqsave(&fc->lock, flags);
 692		ret = bchannel_senddata(bch, skb);
 693		if (ret > 0) { /* direct TX */
 694			hdlc_fill_fifo(bch);
 695			ret = 0;
 696		}
 697		spin_unlock_irqrestore(&fc->lock, flags);
 698		return ret;
 699	case PH_ACTIVATE_REQ:
 700		spin_lock_irqsave(&fc->lock, flags);
 701		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
 702			ret = modehdlc(bch, ch->protocol);
 703		else
 704			ret = 0;
 705		spin_unlock_irqrestore(&fc->lock, flags);
 706		if (!ret)
 707			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
 708				    NULL, GFP_KERNEL);
 709		break;
 710	case PH_DEACTIVATE_REQ:
 711		spin_lock_irqsave(&fc->lock, flags);
 712		mISDN_clear_bchannel(bch);
 713		modehdlc(bch, ISDN_P_NONE);
 714		spin_unlock_irqrestore(&fc->lock, flags);
 715		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
 716			    NULL, GFP_KERNEL);
 717		ret = 0;
 718		break;
 719	}
 720	if (!ret)
 721		dev_kfree_skb(skb);
 722	return ret;
 723}
 724
 725static void
 726inithdlc(struct fritzcard *fc)
 727{
 728	modehdlc(&fc->bch[0], -1);
 729	modehdlc(&fc->bch[1], -1);
 730}
 731
 732static void
 733clear_pending_hdlc_ints(struct fritzcard *fc)
 734{
 735	u32 val;
 736
 737	val = read_status(fc, 1);
 738	pr_debug("%s: HDLC 1 STA %x\n", fc->name, val);
 739	val = read_status(fc, 2);
 740	pr_debug("%s: HDLC 2 STA %x\n", fc->name, val);
 741}
 742
 743static void
 744reset_avm(struct fritzcard *fc)
 745{
 746	switch (fc->type) {
 747	case AVM_FRITZ_PCI:
 748		fc->ctrlreg = AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER;
 749		break;
 750	case AVM_FRITZ_PCIV2:
 751		fc->ctrlreg = AVM_STATUS0_RESET;
 752		break;
 753	}
 754	if (debug & DEBUG_HW)
 755		pr_notice("%s: reset\n", fc->name);
 756	disable_hwirq(fc);
 757	mdelay(5);
 758	switch (fc->type) {
 759	case AVM_FRITZ_PCI:
 760		fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
 761		disable_hwirq(fc);
 762		outb(AVM_STATUS1_ENA_IOM, fc->addr + 3);
 763		break;
 764	case AVM_FRITZ_PCIV2:
 765		fc->ctrlreg = 0;
 766		disable_hwirq(fc);
 767		break;
 768	}
 769	mdelay(1);
 770	if (debug & DEBUG_HW)
 771		pr_notice("%s: S0/S1 %x/%x\n", fc->name,
 772			  inb(fc->addr + 2), inb(fc->addr + 3));
 773}
 774
 775static int
 776init_card(struct fritzcard *fc)
 777{
 778	int		ret, cnt = 3;
 779	u_long		flags;
 780
 781	reset_avm(fc); /* disable IRQ */
 782	if (fc->type == AVM_FRITZ_PCIV2)
 783		ret = request_irq(fc->irq, avm_fritzv2_interrupt,
 784				  IRQF_SHARED, fc->name, fc);
 785	else
 786		ret = request_irq(fc->irq, avm_fritz_interrupt,
 787				  IRQF_SHARED, fc->name, fc);
 788	if (ret) {
 789		pr_info("%s: couldn't get interrupt %d\n",
 790			fc->name, fc->irq);
 791		return ret;
 792	}
 793	while (cnt--) {
 794		spin_lock_irqsave(&fc->lock, flags);
 795		ret = fc->isac.init(&fc->isac);
 796		if (ret) {
 797			spin_unlock_irqrestore(&fc->lock, flags);
 798			pr_info("%s: ISAC init failed with %d\n",
 799				fc->name, ret);
 800			break;
 801		}
 802		clear_pending_hdlc_ints(fc);
 803		inithdlc(fc);
 804		enable_hwirq(fc);
 805		/* RESET Receiver and Transmitter */
 806		if (fc->type == AVM_FRITZ_PCIV2) {
 807			WriteISAC_V2(fc, ISACX_MASK, 0);
 808			WriteISAC_V2(fc, ISACX_CMDRD, 0x41);
 809		} else {
 810			WriteISAC_V1(fc, ISAC_MASK, 0);
 811			WriteISAC_V1(fc, ISAC_CMDR, 0x41);
 812		}
 813		spin_unlock_irqrestore(&fc->lock, flags);
 814		/* Timeout 10ms */
 815		msleep_interruptible(10);
 816		if (debug & DEBUG_HW)
 817			pr_notice("%s: IRQ %d count %d\n", fc->name,
 818				  fc->irq, fc->irqcnt);
 819		if (!fc->irqcnt) {
 820			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
 821				fc->name, fc->irq, 3 - cnt);
 822			reset_avm(fc);
 823		} else
 824			return 0;
 825	}
 826	free_irq(fc->irq, fc);
 827	return -EIO;
 828}
 829
 830static int
 831channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 832{
 833	return mISDN_ctrl_bchannel(bch, cq);
 834}
 835
 836static int
 837avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 838{
 839	struct bchannel *bch = container_of(ch, struct bchannel, ch);
 840	struct fritzcard *fc = bch->hw;
 841	int ret = -EINVAL;
 842	u_long flags;
 843
 844	pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
 845	switch (cmd) {
 846	case CLOSE_CHANNEL:
 847		test_and_clear_bit(FLG_OPEN, &bch->Flags);
 848		cancel_work_sync(&bch->workq);
 849		spin_lock_irqsave(&fc->lock, flags);
 850		mISDN_clear_bchannel(bch);
 851		modehdlc(bch, ISDN_P_NONE);
 852		spin_unlock_irqrestore(&fc->lock, flags);
 853		ch->protocol = ISDN_P_NONE;
 854		ch->peer = NULL;
 855		module_put(THIS_MODULE);
 856		ret = 0;
 857		break;
 858	case CONTROL_CHANNEL:
 859		ret = channel_bctrl(bch, arg);
 860		break;
 861	default:
 862		pr_info("%s: %s unknown prim(%x)\n", fc->name, __func__, cmd);
 863	}
 864	return ret;
 865}
 866
 867static int
 868channel_ctrl(struct fritzcard  *fc, struct mISDN_ctrl_req *cq)
 869{
 870	int	ret = 0;
 871
 872	switch (cq->op) {
 873	case MISDN_CTRL_GETOP:
 874		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
 875		break;
 876	case MISDN_CTRL_LOOP:
 877		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
 878		if (cq->channel < 0 || cq->channel > 3) {
 879			ret = -EINVAL;
 880			break;
 881		}
 882		ret = fc->isac.ctrl(&fc->isac, HW_TESTLOOP, cq->channel);
 883		break;
 884	case MISDN_CTRL_L1_TIMER3:
 885		ret = fc->isac.ctrl(&fc->isac, HW_TIMER3_VALUE, cq->p1);
 886		break;
 887	default:
 888		pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
 889		ret = -EINVAL;
 890		break;
 891	}
 892	return ret;
 893}
 894
 895static int
 896open_bchannel(struct fritzcard *fc, struct channel_req *rq)
 897{
 898	struct bchannel		*bch;
 899
 900	if (rq->adr.channel == 0 || rq->adr.channel > 2)
 901		return -EINVAL;
 902	if (rq->protocol == ISDN_P_NONE)
 903		return -EINVAL;
 904	bch = &fc->bch[rq->adr.channel - 1];
 905	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
 906		return -EBUSY; /* b-channel can be only open once */
 907	bch->ch.protocol = rq->protocol;
 908	rq->ch = &bch->ch;
 909	return 0;
 910}
 911
 912/*
 913 * device control function
 914 */
 915static int
 916avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 917{
 918	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
 919	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
 920	struct fritzcard	*fc = dch->hw;
 921	struct channel_req	*rq;
 922	int			err = 0;
 923
 924	pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
 925	switch (cmd) {
 926	case OPEN_CHANNEL:
 927		rq = arg;
 928		if (rq->protocol == ISDN_P_TE_S0)
 929			err = fc->isac.open(&fc->isac, rq);
 930		else
 931			err = open_bchannel(fc, rq);
 932		if (err)
 933			break;
 934		if (!try_module_get(THIS_MODULE))
 935			pr_info("%s: cannot get module\n", fc->name);
 936		break;
 937	case CLOSE_CHANNEL:
 938		pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id,
 939			 __builtin_return_address(0));
 940		module_put(THIS_MODULE);
 941		break;
 942	case CONTROL_CHANNEL:
 943		err = channel_ctrl(fc, arg);
 944		break;
 945	default:
 946		pr_debug("%s: %s unknown command %x\n",
 947			 fc->name, __func__, cmd);
 948		return -EINVAL;
 949	}
 950	return err;
 951}
 952
 953static int
 954setup_fritz(struct fritzcard *fc)
 955{
 956	u32 val, ver;
 957
 958	if (!request_region(fc->addr, 32, fc->name)) {
 959		pr_info("%s: AVM config port %x-%x already in use\n",
 960			fc->name, fc->addr, fc->addr + 31);
 961		return -EIO;
 962	}
 963	switch (fc->type) {
 964	case AVM_FRITZ_PCI:
 965		val = inl(fc->addr);
 966		outl(AVM_HDLC_1, fc->addr + CHIP_INDEX);
 967		ver = inl(fc->addr + CHIP_WINDOW + HDLC_STATUS) >> 24;
 968		if (debug & DEBUG_HW) {
 969			pr_notice("%s: PCI stat %#x\n", fc->name, val);
 970			pr_notice("%s: PCI Class %X Rev %d\n", fc->name,
 971				  val & 0xff, (val >> 8) & 0xff);
 972			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
 973		}
 974		ASSIGN_FUNC(V1, ISAC, fc->isac);
 975		fc->isac.type = IPAC_TYPE_ISAC;
 976		break;
 977	case AVM_FRITZ_PCIV2:
 978		val = inl(fc->addr);
 979		ver = inl(fc->addr + AVM_HDLC_STATUS_1) >> 24;
 980		if (debug & DEBUG_HW) {
 981			pr_notice("%s: PCI V2 stat %#x\n", fc->name, val);
 982			pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name,
 983				  val & 0xff, (val >> 8) & 0xff);
 984			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
 985		}
 986		ASSIGN_FUNC(V2, ISAC, fc->isac);
 987		fc->isac.type = IPAC_TYPE_ISACX;
 988		break;
 989	default:
 990		release_region(fc->addr, 32);
 991		pr_info("%s: AVM unknown type %d\n", fc->name, fc->type);
 992		return -ENODEV;
 993	}
 994	pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name,
 995		  (fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
 996		  "AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
 997	return 0;
 998}
 999
1000static void
1001release_card(struct fritzcard *card)
1002{
1003	u_long flags;
1004
1005	disable_hwirq(card);
1006	spin_lock_irqsave(&card->lock, flags);
1007	modehdlc(&card->bch[0], ISDN_P_NONE);
1008	modehdlc(&card->bch[1], ISDN_P_NONE);
1009	spin_unlock_irqrestore(&card->lock, flags);
1010	card->isac.release(&card->isac);
1011	free_irq(card->irq, card);
1012	mISDN_freebchannel(&card->bch[1]);
1013	mISDN_freebchannel(&card->bch[0]);
1014	mISDN_unregister_device(&card->isac.dch.dev);
1015	release_region(card->addr, 32);
1016	pci_disable_device(card->pdev);
1017	pci_set_drvdata(card->pdev, NULL);
1018	write_lock_irqsave(&card_lock, flags);
1019	list_del(&card->list);
1020	write_unlock_irqrestore(&card_lock, flags);
1021	kfree(card);
1022	AVM_cnt--;
1023}
1024
1025static int
1026setup_instance(struct fritzcard *card)
1027{
1028	int i, err;
1029	unsigned short minsize;
1030	u_long flags;
1031
1032	snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
1033	write_lock_irqsave(&card_lock, flags);
1034	list_add_tail(&card->list, &Cards);
1035	write_unlock_irqrestore(&card_lock, flags);
1036
1037	_set_debug(card);
1038	card->isac.name = card->name;
1039	spin_lock_init(&card->lock);
1040	card->isac.hwlock = &card->lock;
1041	mISDNisac_init(&card->isac, card);
1042
1043	card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1044		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1045	card->isac.dch.dev.D.ctrl = avm_dctrl;
1046	for (i = 0; i < 2; i++) {
1047		card->bch[i].nr = i + 1;
1048		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
1049		if (AVM_FRITZ_PCIV2 == card->type)
1050			minsize = HDLC_FIFO_SIZE_V2;
1051		else
1052			minsize = HDLC_FIFO_SIZE_V1;
1053		mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize);
1054		card->bch[i].hw = card;
1055		card->bch[i].ch.send = avm_l2l1B;
1056		card->bch[i].ch.ctrl = avm_bctrl;
1057		card->bch[i].ch.nr = i + 1;
1058		list_add(&card->bch[i].ch.list, &card->isac.dch.dev.bchannels);
1059	}
1060	err = setup_fritz(card);
1061	if (err)
1062		goto error;
1063	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
1064				    card->name);
1065	if (err)
1066		goto error_reg;
1067	err = init_card(card);
1068	if (!err)  {
1069		AVM_cnt++;
1070		pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt);
1071		return 0;
1072	}
1073	mISDN_unregister_device(&card->isac.dch.dev);
1074error_reg:
1075	release_region(card->addr, 32);
1076error:
1077	card->isac.release(&card->isac);
1078	mISDN_freebchannel(&card->bch[1]);
1079	mISDN_freebchannel(&card->bch[0]);
1080	write_lock_irqsave(&card_lock, flags);
1081	list_del(&card->list);
1082	write_unlock_irqrestore(&card_lock, flags);
1083	kfree(card);
1084	return err;
1085}
1086
1087static int
1088fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1089{
1090	int err = -ENOMEM;
1091	struct fritzcard *card;
1092
1093	card = kzalloc(sizeof(struct fritzcard), GFP_KERNEL);
1094	if (!card) {
1095		pr_info("No kmem for fritzcard\n");
1096		return err;
1097	}
1098	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
1099		card->type = AVM_FRITZ_PCIV2;
1100	else
1101		card->type = AVM_FRITZ_PCI;
1102	card->pdev = pdev;
1103	err = pci_enable_device(pdev);
1104	if (err) {
1105		kfree(card);
1106		return err;
1107	}
1108
1109	pr_notice("mISDN: found adapter %s at %s\n",
1110		  (char *) ent->driver_data, pci_name(pdev));
1111
1112	card->addr = pci_resource_start(pdev, 1);
1113	card->irq = pdev->irq;
1114	pci_set_drvdata(pdev, card);
1115	err = setup_instance(card);
1116	if (err)
1117		pci_set_drvdata(pdev, NULL);
1118	return err;
1119}
1120
1121static void
1122fritz_remove_pci(struct pci_dev *pdev)
1123{
1124	struct fritzcard *card = pci_get_drvdata(pdev);
1125
1126	if (card)
1127		release_card(card);
1128	else
1129		if (debug)
1130			pr_info("%s: drvdata already removed\n", __func__);
1131}
1132
1133static const struct pci_device_id fcpci_ids[] = {
1134	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID,
1135	  0, 0, (unsigned long) "Fritz!Card PCI"},
1136	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
1137	  0, 0, (unsigned long) "Fritz!Card PCI v2" },
1138	{ }
1139};
1140MODULE_DEVICE_TABLE(pci, fcpci_ids);
1141
1142static struct pci_driver fcpci_driver = {
1143	.name = "fcpci",
1144	.probe = fritzpci_probe,
1145	.remove = fritz_remove_pci,
1146	.id_table = fcpci_ids,
1147};
1148
1149static int __init AVM_init(void)
1150{
1151	int err;
1152
1153	pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV);
1154	err = pci_register_driver(&fcpci_driver);
1155	return err;
1156}
1157
1158static void __exit AVM_cleanup(void)
1159{
1160	pci_unregister_driver(&fcpci_driver);
1161}
1162
1163module_init(AVM_init);
1164module_exit(AVM_cleanup);
~/ Read-only file preview.