hisax_hfcpci.c
来自「是关于linux2.5.1的完全源码」· C语言 代码 · 共 1,647 行 · 第 1/3 页
C
1,647 行
/* * Driver for HFC PCI based cards * * Author Kai Germaschewski * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de> * 2000 by Karsten Keil <keil@isdn4linux.de> * 2000 by Werner Cornelius <werner@isdn4linux.de> * * based upon Werner Cornelius's original hfc_pci.c driver * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */// XXX timer3#include <linux/version.h>#include <linux/module.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/isapnp.h>#include <linux/kmod.h>#include <linux/slab.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <asm/delay.h>#include "hisax_hfcpci.h"// debugging cruft#define __debug_variable debug#include "hisax_debug.h"#ifdef CONFIG_HISAX_DEBUGstatic int debug = 0;MODULE_PARM(debug, "i");#endifMODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Werner Cornelius <werner@isdn4linux.de>");MODULE_DESCRIPTION("HFC PCI ISDN driver");#define ID(ven, dev, name) \ { vendor: PCI_VENDOR_ID_##ven, \ device: PCI_DEVICE_ID_##dev, \ subvendor: PCI_ANY_ID, \ subdevice: PCI_ANY_ID, \ class: 0, \ class_mask: 0, \ driver_data: (unsigned long) name }static struct pci_device_id hfcpci_ids[] __devinitdata = { ID(CCD, CCD_2BD0, "CCD/Billion/Asuscom 2BD0"), ID(CCD, CCD_B000, "Billion B000"), ID(CCD, CCD_B006, "Billion B006"), ID(CCD, CCD_B007, "Billion B007"), ID(CCD, CCD_B008, "Billion B008"), ID(CCD, CCD_B009, "Billion B009"), ID(CCD, CCD_B00A, "Billion B00A"), ID(CCD, CCD_B00B, "Billion B00B"), ID(CCD, CCD_B00C, "Billion B00C"), ID(CCD, CCD_B100, "Seyeon"), ID(ABOCOM, ABOCOM_2BD1, "Abocom/Magitek"), ID(ASUSTEK, ASUSTEK_0675, "Asuscom/Askey"), ID(BERKOM, BERKOM_T_CONCEPT, "German Telekom T-Concept"), ID(BERKOM, BERKOM_A1T, "German Telekom A1T"), ID(ANIGMA, ANIGMA_MC145575, "Motorola MC145575"), ID(ZOLTRIX, ZOLTRIX_2BD0, "Zoltrix 2BD0"), ID(DIGI, DIGI_DF_M_IOM2_E, "Digi DataFire Micro V IOM2 (Europe)"), ID(DIGI, DIGI_DF_M_E, "Digi DataFire Micro V (Europe)"), ID(DIGI, DIGI_DF_M_IOM2_A, "Digi DataFire Micro V IOM2 (America)"), ID(DIGI, DIGI_DF_M_A, "Digi DataFire Micro V (America)"), { } };MODULE_DEVICE_TABLE(pci, hfcpci_ids);#undef IDstatic int protocol = 2; /* EURO-ISDN Default */MODULE_PARM(protocol, "i");// ----------------------------------------------------------------------//#define DBG_WARN 0x0001#define DBG_INFO 0x0002#define DBG_IRQ 0x0010#define DBG_L1M 0x0020#define DBG_PR 0x0040#define DBG_D_XMIT 0x0100#define DBG_D_RECV 0x0200#define DBG_B_XMIT 0x1000#define DBG_B_RECV 0x2000/* memory window base address offset (in config space) */#define HFCPCI_MWBA 0x80/* GCI/IOM bus monitor registers */#define HCFPCI_C_I 0x08#define HFCPCI_TRxR 0x0C#define HFCPCI_MON1_D 0x28#define HFCPCI_MON2_D 0x2C/* GCI/IOM bus timeslot registers */#define HFCPCI_B1_SSL 0x80#define HFCPCI_B2_SSL 0x84#define HFCPCI_AUX1_SSL 0x88#define HFCPCI_AUX2_SSL 0x8C#define HFCPCI_B1_RSL 0x90#define HFCPCI_B2_RSL 0x94#define HFCPCI_AUX1_RSL 0x98#define HFCPCI_AUX2_RSL 0x9C/* GCI/IOM bus data registers */#define HFCPCI_B1_D 0xA0#define HFCPCI_B2_D 0xA4#define HFCPCI_AUX1_D 0xA8#define HFCPCI_AUX2_D 0xAC/* GCI/IOM bus configuration registers */#define HFCPCI_MST_EMOD 0xB4#define HFCPCI_MST_MODE 0xB8#define HFCPCI_CONNECT 0xBC/* Interrupt and status registers */#define HFCPCI_FIFO_EN 0x44#define HFCPCI_TRM 0x48#define HFCPCI_B_MODE 0x4C#define HFCPCI_CHIP_ID 0x58#define HFCPCI_CIRM 0x60#define HFCPCI_CTMT 0x64#define HFCPCI_INT_M1 0x68#define HFCPCI_INT_M2 0x6C#define HFCPCI_INT_S1 0x78#define HFCPCI_INT_S2 0x7C#define HFCPCI_STATUS 0x70/* S/T section registers */#define HFCPCI_STATES 0xC0#define HFCPCI_SCTRL 0xC4#define HFCPCI_SCTRL_E 0xC8#define HFCPCI_SCTRL_R 0xCC#define HFCPCI_SQ 0xD0#define HFCPCI_CLKDEL 0xDC#define HFCPCI_B1_REC 0xF0#define HFCPCI_B1_SEND 0xF0#define HFCPCI_B2_REC 0xF4#define HFCPCI_B2_SEND 0xF4#define HFCPCI_D_REC 0xF8#define HFCPCI_D_SEND 0xF8#define HFCPCI_E_REC 0xFC/* bits in status register (READ) */#define HFCPCI_PCI_PROC 0x02#define HFCPCI_NBUSY 0x04 #define HFCPCI_TIMER_ELAP 0x10#define HFCPCI_STATINT 0x20#define HFCPCI_FRAMEINT 0x40#define HFCPCI_ANYINT 0x80/* bits in CTMT (Write) */#define HFCPCI_CLTIMER 0x80#define HFCPCI_TIM3_125 0x04#define HFCPCI_TIM25 0x10#define HFCPCI_TIM50 0x14#define HFCPCI_TIM400 0x18#define HFCPCI_TIM800 0x1C#define HFCPCI_AUTO_TIMER 0x20#define HFCPCI_TRANSB2 0x02#define HFCPCI_TRANSB1 0x01/* bits in CIRM (Write) */#define HFCPCI_AUX_MSK 0x07#define HFCPCI_RESET 0x08#define HFCPCI_B1_REV 0x40#define HFCPCI_B2_REV 0x80/* bits in INT_M1 and INT_S1 */#define HFCPCI_INTS_B1TRANS 0x01#define HFCPCI_INTS_B2TRANS 0x02#define HFCPCI_INTS_DTRANS 0x04#define HFCPCI_INTS_B1REC 0x08#define HFCPCI_INTS_B2REC 0x10#define HFCPCI_INTS_DREC 0x20#define HFCPCI_INTS_L1STATE 0x40#define HFCPCI_INTS_TIMER 0x80/* bits in INT_M2 */#define HFCPCI_PROC_TRANS 0x01#define HFCPCI_GCI_I_CHG 0x02#define HFCPCI_GCI_MON_REC 0x04#define HFCPCI_IRQ_ENABLE 0x08#define HFCPCI_PMESEL 0x80/* bits in STATES */#define HFCPCI_STATE_MSK 0x0F#define HFCPCI_LOAD_STATE 0x10#define HFCPCI_ACTIVATE 0x20#define HFCPCI_DO_ACTION 0x40#define HFCPCI_NT_G2_G3 0x80/* bits in HFCD_MST_MODE */#define HFCPCI_MASTER 0x01#define HFCPCI_SLAVE 0x00/* remaining bits are for codecs control *//* bits in HFCD_SCTRL */#define SCTRL_B1_ENA 0x01#define SCTRL_B2_ENA 0x02#define SCTRL_MODE_TE 0x00#define SCTRL_MODE_NT 0x04#define SCTRL_LOW_PRIO 0x08#define SCTRL_SQ_ENA 0x10#define SCTRL_TEST 0x20#define SCTRL_NONE_CAP 0x40#define SCTRL_PWR_DOWN 0x80/* bits in SCTRL_E */#define HFCPCI_AUTO_AWAKE 0x01#define HFCPCI_DBIT_1 0x04#define HFCPCI_IGNORE_COL 0x08#define HFCPCI_CHG_B1_B2 0x80/* bits in FIFO_EN register */#define HFCPCI_FIFOEN_B1 0x03#define HFCPCI_FIFOEN_B2 0x0C#define HFCPCI_FIFOEN_DTX 0x10#define HFCPCI_FIFOEN_DRX 0x20#define HFCPCI_FIFOEN_B1TX 0x01#define HFCPCI_FIFOEN_B1RX 0x02#define HFCPCI_FIFOEN_B2TX 0x04#define HFCPCI_FIFOEN_B2RX 0x08/* * thresholds for transparent B-channel mode * change mask and threshold simultaneously */#define HFCPCI_BTRANS_THRESHOLD 128#define HFCPCI_BTRANS_THRESMASK 0x00#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */#define MAX_D_FRAMES 0x10#define MAX_B_FRAMES 0x20#define B_FIFO_START 0x0200#define B_FIFO_END 0x2000#define B_FIFO_SIZE (B_FIFO_END - B_FIFO_START)#define D_FIFO_START 0x0000#define D_FIFO_END 0x0200#define D_FIFO_SIZE (D_FIFO_END - D_FIFO_START)// ----------------------------------------------------------------------// push messages to the upper layersstatic inline void D_L1L2(struct hfcpci_adapter *adapter, int pr, void *arg){ struct hisax_if *ifc = (struct hisax_if *) &adapter->d_if; DBG(DBG_PR, "pr %#x", pr); ifc->l1l2(ifc, pr, arg);}static inline void B_L1L2(struct hfcpci_bcs *bcs, int pr, void *arg){ struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if; DBG(DBG_PR, "pr %#x", pr); ifc->l1l2(ifc, pr, arg);}// ----------------------------------------------------------------------// MMIOstatic inline voidhfcpci_writeb(struct hfcpci_adapter *adapter, u8 b, unsigned char offset){ writeb(b, adapter->mmio + offset);}static inline u8hfcpci_readb(struct hfcpci_adapter *adapter, unsigned char offset){ return readb(adapter->mmio + offset);}// ----------------------------------------------------------------------// magic to define the various F/Z counter accesses#define DECL_B_F(r, f) \static inline u8 \get_b_##r##_##f (struct hfcpci_bcs *bcs) \{ \ u16 off = bcs->channel ? OFF_B2_##r##_##f : OFF_B1_##r##_##f; \ \ return *(bcs->adapter->fifo + off); \} \ \static inline void \set_b_##r##_##f (struct hfcpci_bcs *bcs, u8 f) \{ \ u16 off = bcs->channel ? OFF_B2_##r##_##f : OFF_B1_##r##_##f; \ \ *(bcs->adapter->fifo + off) = f; \}#define OFF_B1_rx_f1 0x6080#define OFF_B2_rx_f1 0x6180#define OFF_B1_rx_f2 0x6081#define OFF_B2_rx_f2 0x6181#define OFF_B1_tx_f1 0x2080#define OFF_B2_tx_f1 0x2180#define OFF_B1_tx_f2 0x2081#define OFF_B2_tx_f2 0x2181DECL_B_F(rx, f1)DECL_B_F(rx, f2)DECL_B_F(tx, f1)DECL_B_F(tx, f2)#undef DECL_B_F#define DECL_B_Z(r, z) \static inline u16 \get_b_##r##_##z (struct hfcpci_bcs *bcs, u8 f) \{ \ u16 off = bcs->channel ? OFF_B2_##r##_##z : OFF_B1_##r##_##z; \ \ return le16_to_cpu(*((u16 *) (bcs->adapter->fifo + off + f * 4))); \} \ \static inline void \set_b_##r##_##z(struct hfcpci_bcs *bcs, u8 f, u16 z) \{ \ u16 off = bcs->channel ? OFF_B2_##r##_##z : OFF_B1_##r##_##z; \ \ *((u16 *) (bcs->adapter->fifo + off + f * 4)) = cpu_to_le16(z); \}#define OFF_B1_rx_z1 0x6000#define OFF_B2_rx_z1 0x6100#define OFF_B1_rx_z2 0x6002#define OFF_B2_rx_z2 0x6102#define OFF_B1_tx_z1 0x2000#define OFF_B2_tx_z1 0x2100#define OFF_B1_tx_z2 0x2002#define OFF_B2_tx_z2 0x2102DECL_B_Z(rx, z1)DECL_B_Z(rx, z2)DECL_B_Z(tx, z1)DECL_B_Z(tx, z2)#undef DECL_B_Z#define DECL_D_F(r, f) \static inline u8 \get_d_##r##_##f (struct hfcpci_adapter *adapter) \{ \ u16 off = OFF_D_##r##_##f; \ \ return *(adapter->fifo + off) & 0xf; \} \ \static inline void \set_d_##r##_##f (struct hfcpci_adapter *adapter, u8 f) \{ \ u16 off = OFF_D_##r##_##f; \ \ *(adapter->fifo + off) = f | 0x10; \}#define OFF_D_rx_f1 0x60a0#define OFF_D_rx_f2 0x60a1#define OFF_D_tx_f1 0x20a0#define OFF_D_tx_f2 0x20a1DECL_D_F(rx, f1)DECL_D_F(rx, f2)DECL_D_F(tx, f1)DECL_D_F(tx, f2)#undef DECL_D_F#define DECL_D_Z(r, z) \static inline u16 \get_d_##r##_##z (struct hfcpci_adapter *adapter, u8 f) \{ \ u16 off = OFF_D_##r##_##z; \ \ return le16_to_cpu(*((u16 *) (adapter->fifo + off + (f | 0x10) * 4)));\} \ \static inline void \set_d_##r##_##z(struct hfcpci_adapter *adapter, u8 f, u16 z) \{ \ u16 off = OFF_D_##r##_##z; \ \ *((u16 *) (adapter->fifo + off + (f | 0x10) * 4)) = cpu_to_le16(z); \}#define OFF_D_rx_z1 0x6080#define OFF_D_rx_z2 0x6082#define OFF_D_tx_z1 0x2080#define OFF_D_tx_z2 0x2082DECL_D_Z(rx, z1)DECL_D_Z(rx, z2)DECL_D_Z(tx, z1)DECL_D_Z(tx, z2)#undef DECL_B_Z// ----------------------------------------------------------------------// fill b / d fifosstatic inline voidhfcpci_fill_d_fifo(struct hfcpci_adapter *adapter){ u8 f1, f2; u16 z1, z2; int cnt, fcnt; char *fifo_adr = adapter->fifo; struct sk_buff *tx_skb = adapter->tx_skb; f1 = get_d_tx_f1(adapter); f2 = get_d_tx_f2(adapter); DBG(DBG_D_XMIT, "f1 %#x f2 %#x", f1, f2); fcnt = f1 - f2; if (fcnt < 0) fcnt += MAX_D_FRAMES; if (fcnt) { printk("BUG\n"); return; } z1 = get_d_tx_z1(adapter, f1); z2 = get_d_tx_z2(adapter, f1); //XXX DBG(DBG_D_XMIT, "z1 %#x z2 %#x", z1, z2); cnt = z2 - z1; if (cnt <= 0) cnt += D_FIFO_SIZE; if (tx_skb->len > cnt) { printk("BUG\n"); return; } cnt = tx_skb->len; if (z1 + cnt <= D_FIFO_END) { memcpy(fifo_adr + z1, tx_skb->data, cnt); } else { memcpy(fifo_adr + z1, tx_skb->data, D_FIFO_END - z1); memcpy(fifo_adr + D_FIFO_START, tx_skb->data + (D_FIFO_END - z1), cnt - (D_FIFO_END - z1)); } z1 += cnt; if (z1 >= D_FIFO_END) z1 -= D_FIFO_SIZE; f1 = (f1 + 1) & (MAX_D_FRAMES - 1); mb(); set_d_tx_z1(adapter, f1, z1); mb(); set_d_tx_f1(adapter, f1);}static inline voidhfcpci_fill_b_fifo_hdlc(struct hfcpci_bcs *bcs){ u8 f1, f2; u16 z1, z2; int cnt, fcnt; char *fifo_adr = bcs->adapter->fifo + (bcs->channel ? 0x2000 : 0x0000); struct sk_buff *tx_skb = bcs->tx_skb; f1 = get_b_tx_f1(bcs); f2 = get_b_tx_f2(bcs); DBG(DBG_B_XMIT, "f1 %#x f2 %#x", f1, f2); fcnt = f1 - f2; if (fcnt < 0) fcnt += MAX_B_FRAMES; if (fcnt) { printk("BUG\n"); return; } z1 = get_b_tx_z1(bcs, f1); z2 = get_b_tx_z2(bcs, f1); //XXX DBG(DBG_B_XMIT, "z1 %#x z2 %#x", z1, z2); cnt = z2 - z1; if (cnt <= 0) cnt += B_FIFO_SIZE; if (tx_skb->len > cnt) { printk("BUG\n"); return; } cnt = tx_skb->len; if (z1 + cnt <= B_FIFO_END) { memcpy(fifo_adr + z1, tx_skb->data, cnt); } else { memcpy(fifo_adr + z1, tx_skb->data, B_FIFO_END - z1); memcpy(fifo_adr + B_FIFO_START, tx_skb->data + (B_FIFO_END - z1), cnt - (B_FIFO_END - z1)); } z1 += cnt; if (z1 >= B_FIFO_END) z1 -= B_FIFO_SIZE; f1 = (f1 + 1) & (MAX_B_FRAMES - 1); mb(); set_b_tx_z1(bcs, f1, z1); mb(); set_b_tx_f1(bcs, f1);}static inline voidhfcpci_fill_b_fifo_trans(struct hfcpci_bcs *bcs){ int cnt; char *fifo_adr = bcs->adapter->fifo + (bcs->channel ? 0x2000 : 0x0000); struct sk_buff *tx_skb = bcs->tx_skb; u8 f1, f2; u16 z1, z2; f1 = get_b_tx_f1(bcs);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?