11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: hfc_pci.c,v 1.48.2.4 2004/02/11 13:21:33 keil Exp $ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 396de0e252cedffad61b3cb5e05662c591898e69aJan Engelhardt * low level driver for CCD's hfc-pci based cards 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author Werner Cornelius 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * based on existing driver for CCD hfc ISA cards 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright by Werner Cornelius <werner@isdn4linux.de> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * by Karsten Keil <keil@isdn4linux.de> 998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For changes and modifications please read 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Documentation/isdn/HiSax.cert 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hisax.h" 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hfc_pci.h" 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isdnl1.h" 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 23d43c36dc6b357fa1806800f18aa30123c747a6d1Alexey Dobriyan#include <linux/sched.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *hfcpci_revision = "$Revision: 1.48.2.4 $"; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* table entry in the PCI devices list */ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct { 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int vendor_id; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int device_id; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *vendor_name; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *card_name; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} PCI_ENTRY; 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define NT_T1_COUNT 20 /* number of 3.125ms interrupts for G2 timeout */ 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */ 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const PCI_ENTRY id_list[] = 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"}, 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"}, 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"}, 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"}, 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"}, 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"}, 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"}, 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"}, 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"}, 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"}, 521e4b27df55166ce3b276f55bab223fa4ae8c5525Karsten Keil {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, "Primux II S0", "B700"}, 531e4b27df55166ce3b276f55bab223fa4ae8c5525Karsten Keil {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, "Primux II S0 NT", "B701"}, 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"}, 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"}, 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"}, 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"}, 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"}, 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"}, 60475be4d85a274d0961593db41cf85689db1d583cJoe Perches {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E, "Digi International", "Digi DataFire Micro V IOM2 (Europe)"}, 61475be4d85a274d0961593db41cf85689db1d583cJoe Perches {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E, "Digi International", "Digi DataFire Micro V (Europe)"}, 62475be4d85a274d0961593db41cf85689db1d583cJoe Perches {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A, "Digi International", "Digi DataFire Micro V IOM2 (North America)"}, 63475be4d85a274d0961593db41cf85689db1d583cJoe Perches {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A, "Digi International", "Digi DataFire Micro V (North America)"}, 64a063cf5b7dde94d98f3f7c9f1c951e02c6564022Karsten Keil {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2, "Sitecom Europe", "DC-105 ISDN PCI"}, 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0, 0, NULL, NULL}, 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************/ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* free hardware resources used by driver */ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************/ 72672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrelease_io_hfcpci(struct IsdnCardState *cs) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "HiSax: release hfcpci at %p\n", 76475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.pci_io); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(10); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(10); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */ 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&cs->hw.hfcpci.timer); 868a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, 87475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); 888a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil cs->hw.hfcpci.fifos = NULL; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap((void *)cs->hw.hfcpci.pci_io); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************************************************************/ 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* function called to reset the HFC PCI chip. A complete software reset of chip */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* and fifos is done. */ 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************************************************************/ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreset_hfcpci(struct IsdnCardState *cs) 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "HFC_PCI: resetting card\n"); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO + PCI_ENA_MASTER); /* enable memory ports + busmaster */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(10); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(10); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (Read_hfc(cs, HFCPCI_STATUS) & 2) 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "HFC-PCI init bit busy\n"); 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.fifo_en = 0x30; /* only D fifos enabled */ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.trm = 0 + HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */ 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_e = HFCPCI_AUTO_AWAKE; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); /* S/T Auto awake */ 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.bswapped = 0; /* no exchange */ 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.nt_mode = 0; /* we are in TE mode */ 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | 127475be4d85a274d0961593db41cf85689db1d583cJoe Perches HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Clear already pending ints */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (Read_hfc(cs, HFCPCI_INT_S1)); 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 2); /* HFC ST 2 */ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_STATES, 2); /* HFC ST 2 */ 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.mst_m = HFCPCI_MASTER; /* HFC Master Mode */ 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_r = 0; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Init GCI/IOM2 in master mode */ 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Slots 0 and 1 are set for B-chan 1 and 2 */ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* D- and monitor/CI channel are not enabled */ 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* STIO2 is used as data input, B1+B2 from IOM->ST */ 14925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* ST B-channel send disabled -> continuous 1s */ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The IOM slots are always enabled */ 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.conn = 0x36; /* set data flow directions */ 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */ 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */ 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */ 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finally enable IRQ output */ 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (Read_hfc(cs, HFCPCI_INT_S1)); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************/ 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Timer function called when kernel timer expires */ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************/ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_Timer(struct IsdnCardState *cs) 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.timer.expires = jiffies + 75; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* WD RESET */ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcpci.ctmt | 0x80); 173475be4d85a274d0961593db41cf85689db1d583cJoe Perches add_timer(&cs->hw.hfcpci.timer); 174475be4d85a274d0961593db41cf85689db1d583cJoe Perches*/ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************/ 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* schedule a new D-channel task */ 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************/ 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssched_event_D_pci(struct IsdnCardState *cs, int event) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(event, &cs->event); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_work(&cs->tqueue); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************/ 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* schedule a new b_channel task */ 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************/ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_sched_event(struct BCState *bcs, int event) 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(event, &bcs->event); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_work(&bcs->tqueue); 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/************************************************/ 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* select a b-channel entry matching and active */ 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/************************************************/ 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct BCState * 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsSel_BCS(struct IsdnCardState *cs, int channel) 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (&cs->bcs[0]); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (&cs->bcs[1]); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (NULL); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************/ 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* clear the desired B-channel rx fifo */ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************/ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hfcpci_clear_fifo_rx(struct IsdnCardState *cs, int fifo) 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ u_char fifo_state; 218475be4d85a274d0961593db41cf85689db1d583cJoe Perches bzfifo_type *bzr; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fifo) { 221475be4d85a274d0961593db41cf85689db1d583cJoe Perches bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2RX; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 224475be4d85a274d0961593db41cf85689db1d583cJoe Perches bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1RX; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fifo_state) 228475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en ^= fifo_state; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.last_bfifo_cnt[fifo] = 0; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzr->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzr->za[MAX_B_FRAMES].z2 = bzr->za[MAX_B_FRAMES].z1; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzr->f1 = MAX_B_FRAMES; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzr->f2 = bzr->f1; /* init F pointers to remain constant */ 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fifo_state) 236475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en |= fifo_state; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 23898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik} 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************/ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* clear the desired B-channel tx fifo */ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************/ 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hfcpci_clear_fifo_tx(struct IsdnCardState *cs, int fifo) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ u_char fifo_state; 245475be4d85a274d0961593db41cf85689db1d583cJoe Perches bzfifo_type *bzt; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fifo) { 248475be4d85a274d0961593db41cf85689db1d583cJoe Perches bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2TX; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 251475be4d85a274d0961593db41cf85689db1d583cJoe Perches bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1TX; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fifo_state) 255475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en ^= fifo_state; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzt->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzt->f1 = MAX_B_FRAMES; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzt->f2 = bzt->f1; /* init F pointers to remain constant */ 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fifo_state) 262475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en |= fifo_state; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 26498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik} 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************/ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* read a complete B-frame out of the buffer */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************/ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sk_buff 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds* 271475be4d85a274d0961593db41cf85689db1d583cJoe Percheshfcpci_empty_fifo(struct BCState *bcs, bzfifo_type *bz, u_char *bdata, int count) 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *ptr, *ptr1, new_f2; 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int total, maxlen, new_z2; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z_type *zp; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_empty_fifo"); 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds zp = &bz->za[bz->f2]; /* point to Z-Regs */ 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z2 = zp->z2 + count; /* new position in fifo */ 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z2 -= B_FIFO_SIZE; /* buffer wrap */ 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((count > HSCX_BUFMAX + 3) || (count < 4) || 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*(bdata + (zp->z1 - B_SUB_VAL)))) { 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_WARN) 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_empty_fifo: incoming packet invalid length %d or crc", count); 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef ERROR_STATISTIC 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->err_inv++; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->za[new_f2].z2 = new_z2; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->f2 = new_f2; /* next buffer */ 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = NULL; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (!(skb = dev_alloc_skb(count - 3))) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "HFCPCI: receive out of memory\n"); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds total = count; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= 3; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = skb_put(skb, count); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (zp->z2 + count <= B_FIFO_SIZE + B_SUB_VAL) 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = count; /* complete transfer */ 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, maxlen); /* copy data */ 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= maxlen; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count) { /* rest remaining */ 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr += maxlen; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = bdata; /* start of buffer */ 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, count); /* rest */ 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->za[new_f2].z2 = new_z2; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->f2 = new_f2; /* next buffer */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (skb); 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************/ 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* D-channel receive procedure */ 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************/ 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreceive_dmsg(struct IsdnCardState *cs) 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int maxlen; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rcnt, total; 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count = 5; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *ptr, *ptr1; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dfifo_type *df; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z_type *zp; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_rx; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "rec_dmsg blocked"); 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) { 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds zp = &df->za[df->f2 & D_FREG_MASK]; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt = zp->z1 - zp->z2; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt < 0) 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt += D_FIFO_SIZE; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt++; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)", 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->f1, df->f2, zp->z1, zp->z2, rcnt); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (df->data[zp->z1])) { 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_WARN) 357465b1678ebdf5dbd9bc0502358ae472343351c2cMasanari Iida debugl1(cs, "empty_fifo hfcpci packet inv. len %d or crc %d", rcnt, df->data[zp->z1]); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef ERROR_STATISTIC 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->err_rx++; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + rcnt) & (D_FIFO_SIZE - 1); 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((skb = dev_alloc_skb(rcnt - 3))) { 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds total = rcnt; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt -= 3; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = skb_put(skb, rcnt); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (zp->z2 + rcnt <= D_FIFO_SIZE) 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = rcnt; /* complete transfer */ 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = D_FIFO_SIZE - zp->z2; /* maximum */ 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = df->data + zp->z2; /* start of data */ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, maxlen); /* copy data */ 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt -= maxlen; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt) { /* rest remaining */ 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr += maxlen; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = df->data; /* start of buffer */ 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, rcnt); /* rest */ 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + total) & (D_FIFO_SIZE - 1); 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&cs->rq, skb); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sched_event_D_pci(cs, D_RCVBUFREADY); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "HFC-PCI: D receive out of memory\n"); 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************/ 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* check for transparent receive data and read max one threshold size if avail */ 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************/ 397672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 398475be4d85a274d0961593db41cf85689db1d583cJoe Percheshfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type *bz, u_char *bdata) 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *z1r, *z2r; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int new_z2, fcnt, maxlen; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *ptr, *ptr1; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z2r = z1r + 1; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(fcnt = *z1r - *z2r)) 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); /* no data avail */ 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt <= 0) 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt += B_FIFO_SIZE; /* bytes actually buffered */ 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt > HFCPCI_BTRANS_THRESHOLD) 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z2 = *z2r + fcnt; /* new position in fifo */ 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z2 -= B_FIFO_SIZE; /* buffer wrap */ 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = dev_alloc_skb(fcnt))) 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "HFCPCI: receive out of memory\n"); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = skb_put(skb, fcnt); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*z2r + fcnt <= B_FIFO_SIZE + B_SUB_VAL) 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = fcnt; /* complete transfer */ 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = B_FIFO_SIZE + B_SUB_VAL - *z2r; /* maximum */ 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = bdata + (*z2r - B_SUB_VAL); /* start of data */ 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, maxlen); /* copy data */ 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt -= maxlen; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt) { /* rest remaining */ 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr += maxlen; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = bdata; /* start of buffer */ 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, fcnt); /* rest */ 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&bcs->rqueue, skb); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_sched_event(bcs, B_RCVBUFREADY); 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *z2r = new_z2; /* new position */ 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* hfcpci_empty_fifo_trans */ 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**********************************/ 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* B-channel main receive routine */ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**********************************/ 449672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmain_rec_hfcpci(struct BCState *bcs) 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rcnt, real_fifo; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int receive, count = 5; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzfifo_type *bz; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *bdata; 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z_type *zp; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) { 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds real_fifo = 1; 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b1; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds real_fifo = 0; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 470475be4d85a274d0961593db41cf85689db1d583cJoe PerchesBegin: 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count--; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "rec_data %d blocked", bcs->channel); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bz->f1 != bz->f2) { 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci rec %d f1(%d) f2(%d)", 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel, bz->f1, bz->f2); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds zp = &bz->za[bz->f2]; 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt = zp->z1 - zp->z2; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt < 0) 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt += B_FIFO_SIZE; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt++; 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci rec %d z1(%x) z2(%x) cnt(%d)", 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel, zp->z1, zp->z2, rcnt); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((skb = hfcpci_empty_fifo(bcs, bz, bdata, rcnt))) { 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&bcs->rqueue, skb); 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_sched_event(bcs, B_RCVBUFREADY); 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt = bz->f1 - bz->f2; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt < 0) 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt += MAX_B_FRAMES + 1; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->hw.hfcpci.last_bfifo_cnt[real_fifo] > rcnt + 1) { 497475be4d85a274d0961593db41cf85689db1d583cJoe Perches rcnt = 0; 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_clear_fifo_rx(cs, real_fifo); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.last_bfifo_cnt[real_fifo] = rcnt; 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt > 1) 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = 1; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = 0; 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (bcs->mode == L1_MODE_TRANS) 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = hfcpci_empty_fifo_trans(bcs, bz, bdata); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = 0; 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count && receive) 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto Begin; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************/ 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* D-channel send routine */ 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************/ 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_fill_dfifo(struct IsdnCardState *cs) 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fcnt; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count, new_z1, maxlen; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dfifo_type *df; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *src, *dst, new_f1; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cs->tx_skb) 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->tx_skb->len <= 0) 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_tx; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_Dfifo f1(%d) f2(%d) z1(f1)(%x)", 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->f1, df->f2, 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->za[df->f1 & D_FREG_MASK].z1); 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt = df->f1 - df->f2; /* frame count actually buffered */ 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt < 0) 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt += (MAX_D_FRAMES + 1); /* if wrap around */ 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt > (MAX_D_FRAMES - 1)) { 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_Dfifo more as 14 frames"); 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef ERROR_STATISTIC 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->err_tx++; 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now determine free bytes in FIFO buffer */ 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = df->za[df->f2 & D_FREG_MASK].z2 - df->za[df->f1 & D_FREG_MASK].z1 - 1; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count <= 0) 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count += D_FIFO_SIZE; /* count now contains available bytes */ 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 5539920239c90d5f6dadfb44325abf3568a5e3fd827Joe Perches debugl1(cs, "hfcpci_fill_Dfifo count(%u/%d)", 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_skb->len, count); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count < cs->tx_skb->len) { 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_Dfifo no fifo mem"); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = cs->tx_skb->len; /* get frame len */ 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z1 = (df->za[df->f1 & D_FREG_MASK].z1 + count) & (D_FIFO_SIZE - 1); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1); 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = cs->tx_skb->data; /* source pointer */ 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = df->data + df->za[df->f1 & D_FREG_MASK].z1; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = D_FIFO_SIZE - df->za[df->f1 & D_FREG_MASK].z1; /* end fifo */ 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (maxlen > count) 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = count; /* limit size */ 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(dst, src, maxlen); /* first copy */ 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= maxlen; /* remaining bytes */ 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count) { 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = df->data; /* start of buffer */ 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src += maxlen; /* new position */ 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(dst, src, count); 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->za[new_f1 & D_FREG_MASK].z1 = new_z1; /* for next buffer */ 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->za[df->f1 & D_FREG_MASK].z1 = new_z1; /* new pos actual buffer */ 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds df->f1 = new_f1; /* next frame */ 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_any(cs->tx_skb); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_skb = NULL; 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************/ 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* B-channel send routine */ 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************/ 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_fill_fifo(struct BCState *bcs) 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int maxlen, fcnt; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count, new_z1; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzfifo_type *bz; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *bdata; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char new_f1, *src, *dst; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *z1t, *z2t; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!bcs->tx_skb) 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb->len <= 0) 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) { 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b2; 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b1; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->mode == L1_MODE_TRANS) { 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z1t = &bz->za[MAX_B_FRAMES].z1; 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z2t = z1t + 1; 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_fifo_trans %d z1(%x) z2(%x)", 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel, *z1t, *z2t); 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt = *z2t - *z1t; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt <= 0) 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt += B_FIFO_SIZE; /* fcnt contains available bytes in fifo */ 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt = B_FIFO_SIZE - fcnt; /* remaining bytes to send */ 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) { 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) { 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* data is suitable for fifo */ 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = bcs->tx_skb->len; 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z1 = *z1t + count; /* new buffer Position */ 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z1 -= B_FIFO_SIZE; /* buffer wrap */ 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = bcs->tx_skb->data; /* source pointer */ 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = bdata + (*z1t - B_SUB_VAL); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = (B_FIFO_SIZE + B_SUB_VAL) - *z1t; /* end of fifo */ 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (maxlen > count) 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = count; /* limit size */ 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(dst, src, maxlen); /* first copy */ 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= maxlen; /* remaining bytes */ 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count) { 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = bdata; /* start of buffer */ 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src += maxlen; /* new position */ 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(dst, src, count); 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_cnt -= bcs->tx_skb->len; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt += bcs->tx_skb->len; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *z1t = new_z1; /* now send data */ 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (cs->debug & L1_DEB_HSCX) 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded", 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel, bcs->tx_skb->len); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 650475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 651475be4d85a274d0961593db41cf85689db1d583cJoe Perches (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&bcs->aclock, flags); 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->ackcnt += bcs->tx_skb->len; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&bcs->aclock, flags); 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_event(bcs, B_ACKPENDING); 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_any(bcs->tx_skb); 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = skb_dequeue(&bcs->squeue); /* fetch next data */ 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_fifo_hdlc %d f1(%d) f2(%d) z1(f1)(%x)", 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel, bz->f1, bz->f2, 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->za[bz->f1].z1); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt = bz->f1 - bz->f2; /* frame count actually buffered */ 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt < 0) 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fcnt += (MAX_B_FRAMES + 1); /* if wrap around */ 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fcnt > (MAX_B_FRAMES - 1)) { 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_Bfifo more as 14 frames"); 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now determine free bytes in FIFO buffer */ 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = bz->za[bz->f2].z2 - bz->za[bz->f1].z1 - 1; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count <= 0) 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count += B_FIFO_SIZE; /* count now contains available bytes */ 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 6849920239c90d5f6dadfb44325abf3568a5e3fd827Joe Perches debugl1(cs, "hfcpci_fill_fifo %d count(%u/%d),%lx", 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel, bcs->tx_skb->len, 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count, current->state); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count < bcs->tx_skb->len) { 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_fifo no fifo mem"); 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = bcs->tx_skb->len; /* get frame len */ 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z1 = bz->za[bz->f1].z1 + count; /* new buffer Position */ 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z1 -= B_FIFO_SIZE; /* buffer wrap */ 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = bcs->tx_skb->data; /* source pointer */ 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = bdata + (bz->za[bz->f1].z1 - B_SUB_VAL); 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = (B_FIFO_SIZE + B_SUB_VAL) - bz->za[bz->f1].z1; /* end fifo */ 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (maxlen > count) 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = count; /* limit size */ 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(dst, src, maxlen); /* first copy */ 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= maxlen; /* remaining bytes */ 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count) { 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = bdata; /* start of buffer */ 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src += maxlen; /* new position */ 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(dst, src, count); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_cnt -= bcs->tx_skb->len; 713475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 714475be4d85a274d0961593db41cf85689db1d583cJoe Perches (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&bcs->aclock, flags); 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->ackcnt += bcs->tx_skb->len; 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&bcs->aclock, flags); 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_event(bcs, B_ACKPENDING); 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->za[new_f1].z1 = new_z1; /* for next buffer */ 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->f1 = new_f1; /* next frame */ 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_any(bcs->tx_skb); 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = NULL; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**********************************************/ 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* D-channel l1 state call for leased NT-mode */ 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**********************************************/ 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdch_nt_l2l1(struct PStack *st, int pr, void *arg) 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 739475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DATA | REQUEST): 740475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | REQUEST): 741475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | INDICATION): 742475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1hw(st, pr, arg); 743475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 744475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_ACTIVATE | REQUEST): 745475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); 746475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 747475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_TESTLOOP | REQUEST): 748475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (1 & (long) arg) 749475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "PH_TEST_LOOP B1"); 750475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (2 & (long) arg) 751475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "PH_TEST_LOOP B2"); 752475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(3 & (long) arg)) 753475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "PH_TEST_LOOP DISABLED"); 754475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg); 755475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 756475be4d85a274d0961593db41cf85689db1d583cJoe Perches default: 757475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug) 758475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr); 759475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***********************/ 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* set/reset echo mode */ 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***********************/ 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 769475be4d85a274d0961593db41cf85689db1d583cJoe Percheshfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = *(unsigned int *) ic->parm.num; 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ic->arg == 98) && 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (!(cs->hw.hfcpci.int_m1 & (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC + HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC)))) { 776475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */ 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 0); /* HFC ST G0 */ 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl |= SCTRL_MODE_NT; 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); /* set NT-mode */ 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 1); /* HFC ST G1 */ 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_STATES, 1 | HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->dc.hfcpci.ph_state = 1; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.nt_mode = 1; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.nt_timer = 0; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->stlist->l2.l2l1 = dch_nt_l2l1; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "NT mode activated"); 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cs->chanlimit > 1) || (cs->hw.hfcpci.bswapped) || 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cs->hw.hfcpci.nt_mode) || (ic->arg != 12)) 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EINVAL); 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&cs->lock, flags); 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i) { 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->logecho = 1; 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.trm |= 0x20; /* enable echo chan */ 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_B2REC; 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2RX; 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->logecho = 0; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.trm &= ~0x20; /* disable echo chan */ 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_B2REC; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2RX; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.conn |= 0x10; /* B2-IOM -> B2-ST */ 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.ctmt &= ~2; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* hfcpci_auxcmd */ 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************/ 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* E-channel receive routine */ 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************/ 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreceive_emsg(struct IsdnCardState *cs) 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rcnt; 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int receive, count = 5; 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bzfifo_type *bz; 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *bdata; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds z_type *zp; 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *ptr, *ptr1, new_f2; 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int total, maxlen, new_z2; 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char e_buffer[256]; 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2; 842475be4d85a274d0961593db41cf85689db1d583cJoe PerchesBegin: 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count--; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "echo_rec_data blocked"); 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bz->f1 != bz->f2) { 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci e_rec f1(%d) f2(%d)", 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->f1, bz->f2); 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds zp = &bz->za[bz->f2]; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt = zp->z1 - zp->z2; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt < 0) 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt += B_FIFO_SIZE; 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt++; 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci e_rec z1(%x) z2(%x) cnt(%d)", 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds zp->z1, zp->z2, rcnt); 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z2 = zp->z2 + rcnt; /* new position in fifo */ 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_z2 -= B_FIFO_SIZE; /* buffer wrap */ 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((rcnt > 256 + 3) || (count < 4) || 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (*(bdata + (zp->z1 - B_SUB_VAL)))) { 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_WARN) 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_empty_echan: incoming packet invalid length %d or crc", rcnt); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->za[new_f2].z2 = new_z2; 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->f2 = new_f2; /* next buffer */ 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds total = rcnt; 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt -= 3; 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = e_buffer; 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (zp->z2 <= B_FIFO_SIZE + B_SUB_VAL) 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = rcnt; /* complete transfer */ 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, maxlen); /* copy data */ 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt -= maxlen; 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt) { /* rest remaining */ 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr += maxlen; 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr1 = bdata; /* start of buffer */ 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(ptr, ptr1, rcnt); /* rest */ 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->za[new_f2].z2 = new_z2; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bz->f2 = new_f2; /* next buffer */ 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & DEB_DLOG_HEX) { 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = cs->dlog; 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((total - 3) < MAX_DLOG_SPACE / 3 - 10) { 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 'E'; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 'C'; 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 'H'; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 'O'; 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = ':'; 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr += QuickHex(ptr, e_buffer, total - 3); 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr--; 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = '\n'; 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr = 0; 90435a4a5733b0a8290de39558b82896ab795b108a7Kees Cook HiSax_putstatus(cs, NULL, "%s", cs->dlog); 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt = bz->f1 - bz->f2; 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt < 0) 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rcnt += MAX_B_FRAMES + 1; 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rcnt > 1) 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = 1; 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = 0; 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive = 0; 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count && receive) 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto Begin; 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* receive_emsg */ 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************/ 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Interrupt handler */ 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************/ 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic irqreturn_t 9287d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellshfcpci_interrupt(int intno, void *dev_id) 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = dev_id; 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char exval; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct BCState *bcs; 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count = 15; 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char val, stat; 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(cs->hw.hfcpci.int_m2 & 0x08)) { 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HFC-PCI: int_m2 %x not initialised", cs->hw.hfcpci.int_m2); 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_NONE; /* not initialised */ 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&cs->lock, flags); 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (HFCPCI_ANYINT & (stat = Read_hfc(cs, HFCPCI_STATUS))) { 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = Read_hfc(cs, HFCPCI_INT_S1); 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HFC-PCI: stat(%02x) s1(%02x)", stat, val); 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_NONE; 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HFC-PCI irq %x %s", val, 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ? 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "locked" : "unlocked"); 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val &= cs->hw.hfcpci.int_m1; 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x40) { /* state machine irq */ 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds exval = Read_hfc(cs, HFCPCI_STATES) & 0xf; 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcpci.ph_state, 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds exval); 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->dc.hfcpci.ph_state = exval; 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sched_event_D_pci(cs, D_L1STATECHANGE); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val &= ~0x40; 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x80) { /* timer irq */ 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->hw.hfcpci.nt_mode) { 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((--cs->hw.hfcpci.nt_timer) < 0) 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sched_event_D_pci(cs, D_L1STATECHANGE); 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val &= ~0x80; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (val) { 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_s1 |= val; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->hw.hfcpci.int_s1 & 0x18) { 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds exval = val; 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = cs->hw.hfcpci.int_s1; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_s1 = exval; 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x08) { 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1 : 0))) { 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug) 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci spurious 0x08 IRQ"); 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds main_rec_hfcpci(bcs); 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x10) { 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->logecho) 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive_emsg(cs); 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (!(bcs = Sel_BCS(cs, 1))) { 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug) 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci spurious 0x10 IRQ"); 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds main_rec_hfcpci(bcs); 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x01) { 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1 : 0))) { 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug) 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci spurious 0x01 IRQ"); 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb) { 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_fifo(bcs); 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "fill_data %d blocked", bcs->channel); 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_fifo(bcs); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "fill_data %d blocked", bcs->channel); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_sched_event(bcs, B_XMTBUFREADY); 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x02) { 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs = Sel_BCS(cs, 1))) { 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug) 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci spurious 0x02 IRQ"); 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb) { 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_fifo(bcs); 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "fill_data %d blocked", bcs->channel); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_fifo(bcs); 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "fill_data %d blocked", bcs->channel); 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_sched_event(bcs, B_XMTBUFREADY); 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x20) { /* receive dframe */ 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive_dmsg(cs); 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x04) { /* dframe transmitted */ 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&cs->dbusytimer); 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sched_event_D_pci(cs, D_CLEARBUSY); 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->tx_skb) { 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->tx_skb->len) { 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_dfifo(cs); 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_dfifo irq blocked"); 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto afterXPR; 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_irq(cs->tx_skb); 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_cnt = 0; 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_skb = NULL; 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cs->tx_skb = skb_dequeue(&cs->sq))) { 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_cnt = 0; 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_dfifo(cs); 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_dfifo irq blocked"); 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sched_event_D_pci(cs, D_XMTBUFREADY); 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1081475be4d85a274d0961593db41cf85689db1d583cJoe Perches afterXPR: 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->hw.hfcpci.int_s1 && count--) { 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = cs->hw.hfcpci.int_s1; 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_s1 = 0; 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HFC-PCI irq %x loop %d", val, 15 - count); 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = 0; 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************************************************/ 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* timer callback for D-chan busy resolution. Currently no function */ 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************************************************/ 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_dbusy_timer(struct IsdnCardState *cs) 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*************************************/ 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Layer 1 D-channel hardware access */ 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*************************************/ 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsHFCPCI_l1hw(struct PStack *st, int pr, void *arg) 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 1113475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DATA | REQUEST): 1114475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & DEB_DLOG_HEX) 1115475be4d85a274d0961593db41cf85689db1d583cJoe Perches LogFrame(cs, skb->data, skb->len); 1116475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & DEB_DLOG_VERBOSE) 1117475be4d85a274d0961593db41cf85689db1d583cJoe Perches dlogframe(cs, skb, 0); 1118475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1119475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->tx_skb) { 1120475be4d85a274d0961593db41cf85689db1d583cJoe Perches skb_queue_tail(&cs->sq, skb); 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef L2FRAME_DEBUG /* psa */ 1122475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & L1_DEB_LAPD) 1123475be4d85a274d0961593db41cf85689db1d583cJoe Perches Logl2Frame(cs, skb, "PH_DATA Queued", 0); 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1125475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_skb = skb; 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->tx_cnt = 0; 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef L2FRAME_DEBUG /* psa */ 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_LAPD) 1130475be4d85a274d0961593db41cf85689db1d583cJoe Perches Logl2Frame(cs, skb, "PH_DATA", 0); 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_dfifo(cs); 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hfcpci_fill_dfifo blocked"); 1137475be4d85a274d0961593db41cf85689db1d583cJoe Perches 1138475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1139475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1140475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1141475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | INDICATION): 1142475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1143475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->tx_skb) { 1144475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & L1_DEB_WARN) 1145475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); 1146475be4d85a274d0961593db41cf85689db1d583cJoe Perches skb_queue_tail(&cs->sq, skb); 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1149475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1150475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & DEB_DLOG_HEX) 1151475be4d85a274d0961593db41cf85689db1d583cJoe Perches LogFrame(cs, skb->data, skb->len); 1152475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & DEB_DLOG_VERBOSE) 1153475be4d85a274d0961593db41cf85689db1d583cJoe Perches dlogframe(cs, skb, 0); 1154475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->tx_skb = skb; 1155475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->tx_cnt = 0; 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef L2FRAME_DEBUG /* psa */ 1157475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & L1_DEB_LAPD) 1158475be4d85a274d0961593db41cf85689db1d583cJoe Perches Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1160475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 1161475be4d85a274d0961593db41cf85689db1d583cJoe Perches hfcpci_fill_dfifo(cs); 1162475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 1163475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else 1164475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "hfcpci_fill_dfifo blocked"); 1165475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1166475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1167475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | REQUEST): 1168475be4d85a274d0961593db41cf85689db1d583cJoe Perches#ifdef L2FRAME_DEBUG /* psa */ 1169475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & L1_DEB_LAPD) 1170475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "-> PH_REQUEST_PULL"); 1171475be4d85a274d0961593db41cf85689db1d583cJoe Perches#endif 1172475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!cs->tx_skb) { 1173475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 1174475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 1175475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else 1176475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 1177475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1178475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (HW_RESET | REQUEST): 1179475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1180475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); /* HFC ST 3 */ 1181475be4d85a274d0961593db41cf85689db1d583cJoe Perches udelay(6); 1182475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, 3); /* HFC ST 2 */ 1183475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; 1184475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); 1185475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); 1186475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1187475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg(cs, HW_POWERUP | CONFIRM, NULL); 1188475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1189475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (HW_ENABLE | REQUEST): 1190475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1191475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, HFCPCI_DO_ACTION); 1192475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1193475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1194475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (HW_DEACTIVATE | REQUEST): 1195475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1196475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER; 1197475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); 1198475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1199475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1200475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (HW_INFO3 | REQUEST): 1201475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1202475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; 1203475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); 1204475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1205475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1206475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (HW_TESTLOOP | REQUEST): 1207475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1208475be4d85a274d0961593db41cf85689db1d583cJoe Perches switch ((long) arg) { 1209475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (1): 1210475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* tx slot */ 1211475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* rx slot */ 1212475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~7) | 1; 1213475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1215475be4d85a274d0961593db41cf85689db1d583cJoe Perches 1216475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (2): 1217475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* tx slot */ 1218475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* rx slot */ 1219475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~0x38) | 0x08; 1220475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1222475be4d85a274d0961593db41cf85689db1d583cJoe Perches 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1224475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_WARN) 1226475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "hfcpci_l1hw loop invalid %4lx", (long) arg); 1227475be4d85a274d0961593db41cf85689db1d583cJoe Perches return; 1228475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1229475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.trm |= 0x80; /* enable IOM-loop */ 1230475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); 1231475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1232475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1233475be4d85a274d0961593db41cf85689db1d583cJoe Perches default: 1234475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->debug & L1_DEB_WARN) 1235475be4d85a274d0961593db41cf85689db1d583cJoe Perches debugl1(cs, "hfcpci_l1hw unknown pr %4x", pr); 1236475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***********************************************/ 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* called during init setting l1 stack pointer */ 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***********************************************/ 1243672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_hfcpci(struct PStack *st, struct IsdnCardState *cs) 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.l1hw = HFCPCI_l1hw; 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************/ 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* send B-channel data if not blocked */ 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************/ 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_send_data(struct BCState *bcs) 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hfcpci_fill_fifo(bcs); 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "send_data %d blocked", bcs->channel); 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************/ 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* activate/deactivate hardware for selected channels and mode */ 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************/ 1267672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmode_hfcpci(struct BCState *bcs, int mode, int bc) 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fifo2; 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HFCPCI bchannel mode %d bchan %d/%d", 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode, bc, bcs->channel); 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->mode = mode; 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel = bc; 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fifo2 = bc; 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->chanlimit > 1) { 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_e &= ~0x80; 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bc) { 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode != L1_MODE_NULL) { 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.bswapped = 1; /* B1 and B2 exchanged */ 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_e |= 0x80; 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_e &= ~0x80; 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fifo2 = 0; 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.sctrl_e &= ~0x80; 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mode) { 1298475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_NULL): 1299475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bc) { 1300475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; 1301475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; 1302475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1303475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl &= ~SCTRL_B1_ENA; 1304475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r &= ~SCTRL_B1_ENA; 1305475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1306475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (fifo2) { 1307475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; 1308475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); 1309475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1310475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; 1311475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); 1312475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1313475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1314475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_TRANS): 1315475be4d85a274d0961593db41cf85689db1d583cJoe Perches hfcpci_clear_fifo_rx(cs, fifo2); 1316475be4d85a274d0961593db41cf85689db1d583cJoe Perches hfcpci_clear_fifo_tx(cs, fifo2); 1317475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bc) { 1318475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; 1319475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; 1320475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1321475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; 1322475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; 1323475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1324475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (fifo2) { 1325475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; 1326475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); 1327475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.ctmt |= 2; 1328475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn &= ~0x18; 1329475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1330475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; 1331475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); 1332475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.ctmt |= 1; 1333475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn &= ~0x03; 1334475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1335475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1336475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_HDLC): 1337475be4d85a274d0961593db41cf85689db1d583cJoe Perches hfcpci_clear_fifo_rx(cs, fifo2); 1338475be4d85a274d0961593db41cf85689db1d583cJoe Perches hfcpci_clear_fifo_tx(cs, fifo2); 1339475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bc) { 1340475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; 1341475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; 1342475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1343475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; 1344475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; 1345475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1346475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (fifo2) { 1347475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.last_bfifo_cnt[1] = 0; 1348475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; 1349475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); 1350475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.ctmt &= ~2; 1351475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn &= ~0x18; 1352475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1353475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.last_bfifo_cnt[0] = 0; 1354475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; 1355475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); 1356475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.ctmt &= ~1; 1357475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn &= ~0x03; 1358475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1359475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1360475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_EXTRN): 1361475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bc) { 1362475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn |= 0x10; 1363475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; 1364475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; 1365475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; 1366475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); 1367475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1368475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.conn |= 0x02; 1369475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; 1370475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; 1371475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; 1372475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); 1373475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1374475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************/ 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Layer2 -> Layer 1 Transfer */ 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************/ 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_l2l1(struct PStack *st, int pr, void *arg) 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct BCState *bcs = st->l1.bcs; 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 1396475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DATA | REQUEST): 1397475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 1398475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bcs->tx_skb) { 1399475be4d85a274d0961593db41cf85689db1d583cJoe Perches skb_queue_tail(&bcs->squeue, skb); 1400475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = skb; 1402475be4d85a274d0961593db41cf85689db1d583cJoe Perches// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->cs->BC_Send_Data(bcs); 1404475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1405475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 1406475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1407475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | INDICATION): 1408475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 1409475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bcs->tx_skb) { 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&bcs->cs->lock, flags); 1411475be4d85a274d0961593db41cf85689db1d583cJoe Perches printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n"); 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1413475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1414475be4d85a274d0961593db41cf85689db1d583cJoe Perches// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 1415475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->tx_skb = skb; 1416475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->cs->BC_Send_Data(bcs); 1417475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 1418475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1419475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | REQUEST): 1420475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!bcs->tx_skb) { 1421475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 1422475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 1423475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else 1424475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 1425475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1426475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_ACTIVATE | REQUEST): 1427475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 1428475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); 1429475be4d85a274d0961593db41cf85689db1d583cJoe Perches mode_hfcpci(bcs, st->l1.mode, st->l1.bc); 1430475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 1431475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg_b(st, pr, arg); 1432475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1433475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DEACTIVATE | REQUEST): 1434475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg_b(st, pr, arg); 1435475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1436475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DEACTIVATE | CONFIRM): 1437475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 1438475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); 1439475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 1440475be4d85a274d0961593db41cf85689db1d583cJoe Perches mode_hfcpci(bcs, 0, st->l1.bc); 1441475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 1442475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 1443475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************/ 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* deactivate B-channel access and queues */ 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************/ 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclose_hfcpci(struct BCState *bcs) 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_hfcpci(bcs, 0, bcs->channel); 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&bcs->rqueue); 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&bcs->squeue); 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb) { 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_any(bcs->tx_skb); 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = NULL; 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*************************************/ 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* init B-channel queues and control */ 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*************************************/ 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsopen_hfcpcistate(struct IsdnCardState *cs, struct BCState *bcs) 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&bcs->rqueue); 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&bcs->squeue); 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = NULL; 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->event = 0; 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_cnt = 0; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************/ 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* inits the stack for B-channel */ 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************/ 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_2b(struct PStack *st, struct BCState *bcs) 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel = st->l1.bc; 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (open_hfcpcistate(st->l1.hardware, bcs)) 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs = bcs; 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1 = hfcpci_l2l1; 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setstack_manager(st); 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->st = st; 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setstack_l1_B(st); 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************/ 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* handle L1 state changes */ 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************/ 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1503c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howellshfcpci_bh(struct work_struct *work) 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1505c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct IsdnCardState *cs = 1506c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells container_of(work, struct IsdnCardState, tqueue); 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// struct PStack *stptr; 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cs->hw.hfcpci.nt_mode) 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cs->dc.hfcpci.ph_state) { 1513475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (0): 1514475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg(cs, HW_RESET | INDICATION, NULL); 1515475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1516475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (3): 1517475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); 1518475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1519475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (8): 1520475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg(cs, HW_RSYNC | INDICATION, NULL); 1521475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1522475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (6): 1523475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg(cs, HW_INFO2 | INDICATION, NULL); 1524475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1525475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (7): 1526475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); 1527475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1528475be4d85a274d0961593db41cf85689db1d583cJoe Perches default: 1529475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1530475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&cs->lock, flags); 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cs->dc.hfcpci.ph_state) { 1533475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (2): 1534475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (cs->hw.hfcpci.nt_timer < 0) { 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.nt_timer = 0; 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 1538475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* Clear already pending ints */ 1539475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (Read_hfc(cs, HFCPCI_INT_S1)); 1540475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); 1541475be4d85a274d0961593db41cf85689db1d583cJoe Perches udelay(10); 1542475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, 4); 1543475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->dc.hfcpci.ph_state = 4; 1544475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1545475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_TIMER; 1546475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 1547475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.ctmt &= ~HFCPCI_AUTO_TIMER; 1548475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.ctmt |= HFCPCI_TIM3_125; 1549475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); 1550475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); 1551475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.nt_timer = NT_T1_COUNT; 1552475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); /* allow G2 -> G3 transition */ 1553475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1554475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1555475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (1): 1556475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (3): 1557475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (4): 1558475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.nt_timer = 0; 1559475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; 1560475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 1561475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1562475be4d85a274d0961593db41cf85689db1d583cJoe Perches default: 1563475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DChannel_proc_rcv(cs); 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DChannel_proc_xmt(cs); 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************/ 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* called for card init message */ 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************/ 157867eb5db5874076db01febed5a1a9281628fa9fb4Karsten Keilstatic void 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinithfcpci(struct IsdnCardState *cs) 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[0].BC_SetStack = setstack_2b; 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[1].BC_SetStack = setstack_2b; 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[0].BC_Close = close_hfcpci; 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[1].BC_Close = close_hfcpci; 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->dbusytimer.function = (void *) hfcpci_dbusy_timer; 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->dbusytimer.data = (long) cs; 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&cs->dbusytimer); 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_hfcpci(cs->bcs, 0, 0); 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode_hfcpci(cs->bcs + 1, 0, 1); 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************/ 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* handle card messages from control layer */ 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************/ 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_ISAC) 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HFCPCI: card_msg %x", mt); 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mt) { 1605475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_RESET: 1606475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1607475be4d85a274d0961593db41cf85689db1d583cJoe Perches reset_hfcpci(cs); 1608475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1609475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 1610475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_RELEASE: 1611475be4d85a274d0961593db41cf85689db1d583cJoe Perches release_io_hfcpci(cs); 1612475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 1613475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_INIT: 1614475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1615475be4d85a274d0961593db41cf85689db1d583cJoe Perches inithfcpci(cs); 1616475be4d85a274d0961593db41cf85689db1d583cJoe Perches reset_hfcpci(cs); 1617475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1618475be4d85a274d0961593db41cf85689db1d583cJoe Perches msleep(80); /* Timeout 80ms */ 1619475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* now switch timer interrupt off */ 1620475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 1621475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; 1622475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 1623475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* reinit mode reg */ 1624475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); 1625475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 1626475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 1627475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_TEST: 1628475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this variable is used as card index when more than one cards are present */ 1635ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic struct pci_dev *dev_hfcpci = NULL; 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1637ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanint 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetup_hfcpci(struct IsdnCard *card) 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = card->cs; 16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char tmp[64]; 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *tmp_hfcpci = NULL; 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(tmp, hfcpci_revision); 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); 164898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.int_s1 = 0; 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->dc.hfcpci.ph_state = 0; 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.hfcpci.fifo = 255; 165298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik if (cs->typ != ISDN_CTYPE_HFC_PCI) 1653475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 165498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 165598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik i = 0; 165698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik while (id_list[i].vendor_id) { 165741a68a748bbc61f5bcea999e33ba72926dfbe6f7Tilman Schmidt tmp_hfcpci = hisax_find_pci_device(id_list[i].vendor_id, 1658475be4d85a274d0961593db41cf85689db1d583cJoe Perches id_list[i].device_id, 1659475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_hfcpci); 166098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik i++; 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp_hfcpci) { 16628a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil dma_addr_t dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL; 166398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik if (pci_enable_device(tmp_hfcpci)) 166498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik continue; 16658a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) { 16668a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil printk(KERN_WARNING 1667475be4d85a274d0961593db41cf85689db1d583cJoe Perches "HiSax hfc_pci: No suitable DMA available.\n"); 16688a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil continue; 16698a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil } 16708a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) { 16718a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil printk(KERN_WARNING 1672475be4d85a274d0961593db41cf85689db1d583cJoe Perches "HiSax hfc_pci: No suitable consistent DMA available.\n"); 16738a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil continue; 16748a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil } 167598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik pci_set_master(tmp_hfcpci); 1676475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[0].start & PCI_BASE_ADDRESS_IO_MASK))) 167798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik continue; 167898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik else 167998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik break; 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 168198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik } 168298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 168398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik if (!tmp_hfcpci) { 168498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); 168598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik return (0); 168698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik } 168798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 168898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik i--; 168998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik dev_hfcpci = tmp_hfcpci; /* old device */ 169098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.dev = dev_hfcpci; 169198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->irq = dev_hfcpci->irq; 169298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik if (!cs->irq) { 169398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); 169498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik return (0); 169598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik } 169698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.pci_io = (char *)(unsigned long)dev_hfcpci->resource[1].start; 169798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); 169898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 169998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik if (!cs->hw.hfcpci.pci_io) { 170098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); 170198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik return (0); 170298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik } 17038a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil 170498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik /* Allocate memory for FIFOS */ 17058a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev, 1706475be4d85a274d0961593db41cf85689db1d583cJoe Perches 0x8000, &cs->hw.hfcpci.dma); 17078a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil if (!cs->hw.hfcpci.fifos) { 17088a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n"); 17098a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil return 0; 17108a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil } 17118a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil if (cs->hw.hfcpci.dma & 0x7fff) { 17128a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil printk(KERN_WARNING 1713475be4d85a274d0961593db41cf85689db1d583cJoe Perches "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n", 1714475be4d85a274d0961593db41cf85689db1d583cJoe Perches (u_long)cs->hw.hfcpci.dma); 17158a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, 1716475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); 171798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik return 0; 171898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik } 17198a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma); 172098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); 172198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik printk(KERN_INFO 17228a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n", 172398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.pci_io, 172498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.fifos, 17258a745b9d91962991ce87a649a4dc3af3206c2c8bKarsten Keil (u_long)cs->hw.hfcpci.dma, 172698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->irq, HZ); 172798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 172898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik spin_lock_irqsave(&cs->lock, flags); 172998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 173098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ 173198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ 173298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.int_m1 = 0; 173398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); 173498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); 173598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik /* At this point the needed PCI config is done */ 173698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik /* fifos are still not enabled */ 173798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 173898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik INIT_WORK(&cs->tqueue, hfcpci_bh); 173998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->setstack_d = setstack_hfcpci; 174098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->BC_Send_Data = &hfcpci_send_data; 174198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->readisac = NULL; 174298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->writeisac = NULL; 174398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->readisacfifo = NULL; 174498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->writeisacfifo = NULL; 174598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->BC_Read_Reg = NULL; 174698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->BC_Write_Reg = NULL; 174798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->irq_func = &hfcpci_interrupt; 174898fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->irq_flags |= IRQF_SHARED; 174998fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer; 175098fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->hw.hfcpci.timer.data = (long) cs; 175198fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik init_timer(&cs->hw.hfcpci.timer); 175298fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->cardmsg = &hfcpci_card_msg; 175398fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik cs->auxcmd = &hfcpci_auxcmd; 175498fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 175598fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik spin_unlock_irqrestore(&cs->lock, flags); 175698fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik 175798fc4839aa00a02da83625e9fedad7a348c0af91Jeff Garzik return (1); 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1759