^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * hfcmulti.c low level driver for hfc-4s/hfc-8s/hfc-e1 based cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author Andreas Eversberg (jolly@eversberg.eu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * ported to mqueue mechanism:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Peter Sprenger (sprengermoving-bytes.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * inspired by existing hfc-pci driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright 1999 by Werner Cornelius (werner@isdn-development.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright 2008 by Karsten Keil (kkeil@suse.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright 2008 by Andreas Eversberg (jolly@eversberg.eu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Thanks to Cologne Chip AG for this great controller!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * module parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * By default (0), the card is automatically detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Or use the following combinations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Bit 0-7 = 0x00001 = HFC-E1 (1 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * or Bit 0-7 = 0x00004 = HFC-4S (4 ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * or Bit 0-7 = 0x00008 = HFC-8S (8 ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Bit 8 = 0x00100 = uLaw (instead of aLaw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Bit 9 = 0x00200 = Disable DTMF detect on all B-channels via hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Bit 10 = spare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Bit 11 = 0x00800 = Force PCM bus into slave mode. (otherwhise auto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * or Bit 12 = 0x01000 = Force PCM bus into master mode. (otherwhise auto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Bit 13 = spare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Bit 14 = 0x04000 = Use external ram (128K)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Bit 15 = 0x08000 = Use external ram (512K)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Bit 16 = 0x10000 = Use 64 timeslots instead of 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * or Bit 17 = 0x20000 = Use 128 timeslots instead of anything else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * Bit 18 = spare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Bit 19 = 0x80000 = Send the Watchdog a Signal (Dual E1 with Watchdog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * (all other bits are reserved and shall be 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * example: 0x20204 one HFC-4S with dtmf detection and 128 timeslots on PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * bus (PCM master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * port: (optional or required for all ports on all installed cards)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * HFC-4S/HFC-8S only bits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Bit 0 = 0x001 = Use master clock for this S/T interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * (ony once per chip).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Bit 1 = 0x002 = transmitter line setup (non capacitive mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Don't use this unless you know what you are doing!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Bit 2 = 0x004 = Disable E-channel. (No E-channel processing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * example: 0x0001,0x0000,0x0000,0x0000 one HFC-4S with master clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * received from port 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * HFC-E1 only bits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Bit 0 = 0x0001 = interface: 0=copper, 1=optical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Bit 1 = 0x0002 = reserved (later for 32 B-channels transparent mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Bit 2 = 0x0004 = Report LOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Bit 3 = 0x0008 = Report AIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Bit 4 = 0x0010 = Report SLIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Bit 5 = 0x0020 = Report RDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Bit 8 = 0x0100 = Turn off CRC-4 Multiframe Mode, use double frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * mode instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Bit 9 = 0x0200 = Force get clock from interface, even in NT mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * or Bit 10 = 0x0400 = Force put clock to interface, even in TE mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Bit 11 = 0x0800 = Use direct RX clock for PCM sync rather than PLL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * (E1 only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * Bit 12-13 = 0xX000 = elastic jitter buffer (1-3), Set both bits to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * for default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * (all other bits are reserved and shall be 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * debug:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * NOTE: only one debug value must be given for all cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * enable debugging (see hfc_multi.h for debug options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * poll:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * NOTE: only one poll value must be given for all cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Give the number of samples for each fifo process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * By default 128 is used. Decrease to reduce delay, increase to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * reduce cpu load. If unsure, don't mess with it!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Valid is 8, 16, 32, 64, 128, 256.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * pcm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * NOTE: only one pcm value must be given for every card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * The PCM bus id tells the mISDNdsp module about the connected PCM bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * By default (0), the PCM bus id is 100 for the card that is PCM master.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * If multiple cards are PCM master (because they are not interconnected),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * each card with PCM master will have increasing PCM id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * All PCM busses with the same ID are expected to be connected and have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * common time slots slots.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Only one chip of the PCM bus must be master, the others slave.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * -1 means no support of PCM bus not even.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Omit this value, if all cards are interconnected or none is connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * If unsure, don't give this parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * dmask and bmask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * NOTE: One dmask value must be given for every HFC-E1 card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * If omitted, the E1 card has D-channel on time slot 16, which is default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * dmask is a 32 bit mask. The bit must be set for an alternate time slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * If multiple bits are set, multiple virtual card fragments are created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * For each bit set, a bmask value must be given. Each bit on the bmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * value stands for a B-channel. The bmask may not overlap with dmask or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * with other bmask values for that card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * This will create one fragment with D-channel on slot 1 with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * B-channels on slots 2..15, and a second fragment with D-channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * on slot 17 with B-channels on slot 18..31. Slot 16 is unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * not function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Example: dmask=0x00000001 bmask=0xfffffffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * This will create a port with all 31 usable timeslots as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * B-channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * If no bits are set on bmask, no B-channel is created for that fragment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * This will create 31 ports with one D-channel only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * If you don't know how to use it, you don't need it!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * iomode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * NOTE: only one mode value must be given for every card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * -> See hfc_multi.h for HFC_IO_MODE_* values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * By default, the IO mode is pci memory IO (MEMIO).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * Some cards require specific IO mode, so it cannot be changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * It may be useful to set IO mode to register io (REGIO) to solve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * PCI bridge problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * If unsure, don't give this parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * clockdelay_nt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * NOTE: only one clockdelay_nt value must be given once for all cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * Give the value of the clock control register (A_ST_CLK_DLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * of the S/T interfaces in NT mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * This register is needed for the TBR3 certification, so don't change it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * clockdelay_te:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * NOTE: only one clockdelay_te value must be given once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Give the value of the clock control register (A_ST_CLK_DLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * of the S/T interfaces in TE mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * This register is needed for the TBR3 certification, so don't change it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * NOTE: only one clock value must be given once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Selects interface with clock source for mISDN and applications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Set to card number starting with 1. Set to -1 to disable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * By default, the first card is used as clock source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * hwid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * NOTE: only one hwid value must be given once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Enable special embedded devices with XHFC controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * debug register access (never use this, it will flood your system log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * #define HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define HFC_MULTI_VERSION "2.03"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #include <linux/mISDNhw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #include <linux/mISDNdsp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define IRQCOUNT_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define IRQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #include "hfc_multi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #ifdef ECHOPREP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #include "gaintab.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define MAX_CARDS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define MAX_PORTS (8 * MAX_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define MAX_FRAGS (32 * MAX_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static LIST_HEAD(HFClist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static spinlock_t HFClock; /* global hfc list lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void ph_state_change(struct dchannel *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct hfc_multi *syncmaster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int plxsd_master; /* if we have a master card (yet) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static spinlock_t plx_lock; /* may not acquire other lock inside */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define TYP_E1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define TYP_4S 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define TYP_8S 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int poll_timer = 6; /* default = 128 samples = 16ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* number of POLL_TIMER interrupts for G2 timeout (ca 1s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define CLKDEL_NT 0x6c /* CLKDEL in NT mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) (0x60 MUST be included!) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define DIP_E1 0x3 /* DIP Switches for Beronet E1 cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * module stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static uint type[MAX_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int pcm[MAX_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static uint dmask[MAX_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static uint bmask[MAX_FRAGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static uint iomode[MAX_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static uint port[MAX_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static uint debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static uint poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static uint timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static uint clockdelay_te = CLKDEL_TE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static uint clockdelay_nt = CLKDEL_NT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define HWID_NONE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define HWID_MINIP4 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define HWID_MINIP8 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define HWID_MINIP16 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static uint hwid = HWID_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) MODULE_AUTHOR("Andreas Eversberg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) MODULE_VERSION(HFC_MULTI_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) module_param(debug, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) module_param(poll, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) module_param(clock, int, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) module_param(timer, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define HFC_outb(hc, reg, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) (hc->HFC_outb(hc, reg, val, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define HFC_outb_nodebug(hc, reg, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) (hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define HFC_inb(hc, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (hc->HFC_inb(hc, reg, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define HFC_inb_nodebug(hc, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) (hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define HFC_inw(hc, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) (hc->HFC_inw(hc, reg, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define HFC_inw_nodebug(hc, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) (hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define HFC_wait(hc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) (hc->HFC_wait(hc, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define HFC_wait_nodebug(hc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (hc->HFC_wait_nodebug(hc, __func__, __LINE__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define HFC_outb(hc, reg, val) (hc->HFC_outb(hc, reg, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define HFC_outb_nodebug(hc, reg, val) (hc->HFC_outb_nodebug(hc, reg, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define HFC_inb(hc, reg) (hc->HFC_inb(hc, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) #define HFC_inb_nodebug(hc, reg) (hc->HFC_inb_nodebug(hc, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define HFC_inw(hc, reg) (hc->HFC_inw(hc, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define HFC_inw_nodebug(hc, reg) (hc->HFC_inw_nodebug(hc, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define HFC_wait(hc) (hc->HFC_wait(hc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #ifdef CONFIG_MISDN_HFCMULTI_8xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #include "hfc_multi_8xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* HFC_IO_MODE_PCIMEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) writeb(val, hc->pci_membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static u_char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return readb(hc->pci_membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static u_short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return readw(hc->pci_membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) HFC_wait_pcimem(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) while (readb(hc->pci_membase + R_STATUS) & V_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* HFC_IO_MODE_REGIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) outb(reg, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) outb(val, hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static u_char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) HFC_inb_regio(struct hfc_multi *hc, u_char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) outb(reg, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return inb(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static u_short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) HFC_inw_regio(struct hfc_multi *hc, u_char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) outb(reg, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return inw(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) HFC_wait_regio(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) outb(R_STATUS, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) while (inb(hc->pci_iobase) & V_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) char regname[256] = "", bits[9] = "xxxxxxxx";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) i = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) while (hfc_register_names[++i].name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (hfc_register_names[i].reg == reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) strcat(regname, hfc_register_names[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (regname[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) strcpy(regname, "register");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) bits[7] = '0' + (!!(val & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) bits[6] = '0' + (!!(val & 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) bits[5] = '0' + (!!(val & 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) bits[4] = '0' + (!!(val & 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) bits[3] = '0' + (!!(val & 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) bits[2] = '0' + (!!(val & 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) bits[1] = '0' + (!!(val & 64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) bits[0] = '0' + (!!(val & 128));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) hc->id, reg, regname, val, bits, function, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) HFC_outb_nodebug(hc, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static u_char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) char regname[256] = "", bits[9] = "xxxxxxxx";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) u_char val = HFC_inb_nodebug(hc, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) while (hfc_register_names[i++].name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) while (hfc_register_names[++i].name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (hfc_register_names[i].reg == reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) strcat(regname, hfc_register_names[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (regname[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) strcpy(regname, "register");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) bits[7] = '0' + (!!(val & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) bits[6] = '0' + (!!(val & 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) bits[5] = '0' + (!!(val & 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) bits[4] = '0' + (!!(val & 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bits[3] = '0' + (!!(val & 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) bits[2] = '0' + (!!(val & 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) bits[1] = '0' + (!!(val & 64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) bits[0] = '0' + (!!(val & 128));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) hc->id, reg, regname, val, bits, function, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static u_short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) char regname[256] = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) u_short val = HFC_inw_nodebug(hc, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) while (hfc_register_names[i++].name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) while (hfc_register_names[++i].name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (hfc_register_names[i].reg == reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) strcat(regname, hfc_register_names[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (regname[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) strcpy(regname, "register");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) hc->id, reg, regname, val, function, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) hc->id, function, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* write fifo data (REGIO) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) while (len >> 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) while (len >> 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) data += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) outb(*data, hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* write fifo data (PCIMEM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) while (len >> 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) writel(cpu_to_le32(*(u32 *)data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) hc->pci_membase + A_FIFO_DATA0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) while (len >> 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) writew(cpu_to_le16(*(u16 *)data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) hc->pci_membase + A_FIFO_DATA0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) data += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) writeb(*data, hc->pci_membase + A_FIFO_DATA0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* read fifo data (REGIO) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) while (len >> 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) *(u32 *)data = le32_to_cpu(inl(hc->pci_iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) while (len >> 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) *(u16 *)data = le16_to_cpu(inw(hc->pci_iobase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) data += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *data = inb(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* read fifo data (PCIMEM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) while (len >> 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) *(u32 *)data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) while (len >> 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) *(u16 *)data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) data += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) *data = readb(hc->pci_membase + A_FIFO_DATA0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) enable_hwirq(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) disable_hwirq(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #define NUM_EC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #define MAX_TDM_CHAN 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) enablepcibridge(struct hfc_multi *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) disablepcibridge(struct hfc_multi *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static inline unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) readpcibridge(struct hfc_multi *hc, unsigned char address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) unsigned short cipv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unsigned char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!hc->pci_iobase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* slow down a PCI read access by 1 PCI clock cycle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (address == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) cipv = 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cipv = 0x5800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* select local bridge port address by writing to CIP port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* data = HFC_inb(c, cipv); * was _io before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) outw(cipv, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) data = inb(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* restore R_CTRL for normal PCI read cycle speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) HFC_outb(hc, R_CTRL, 0x0); /* was _io before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unsigned short cipv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) unsigned int datav;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!hc->pci_iobase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (address == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) cipv = 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) cipv = 0x5800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* select local bridge port address by writing to CIP port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) outw(cipv, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* define a 32 bit dword with 4 identical bytes for write sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) datav = data | ((__u32) data << 8) | ((__u32) data << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ((__u32) data << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * write this 32 bit dword to the bridge data port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * this will initiate a write sequence of up to 4 writes to the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * address on the local bus interface the number of write accesses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * is undefined but >=1 and depends on the next PCI transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * during write sequence on the local bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) outl(datav, hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) cpld_set_reg(struct hfc_multi *hc, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* Do data pin read low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) HFC_outb(hc, R_GPIO_OUT1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) cpld_set_reg(hc, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) enablepcibridge(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) writepcibridge(hc, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) disablepcibridge(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static inline unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) cpld_read_reg(struct hfc_multi *hc, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned char bytein;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) cpld_set_reg(hc, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Do data pin read low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) HFC_outb(hc, R_GPIO_OUT1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) enablepcibridge(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) bytein = readpcibridge(hc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) disablepcibridge(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return bytein;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) vpm_write_address(struct hfc_multi *hc, unsigned short addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) cpld_write_reg(hc, 0, 0xff & addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) cpld_write_reg(hc, 1, 0x01 & (addr >> 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static inline unsigned short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) vpm_read_address(struct hfc_multi *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) unsigned short addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) unsigned short highbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) addr = cpld_read_reg(c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) highbit = cpld_read_reg(c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) addr = addr | (highbit << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return addr & 0x1ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static inline unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) vpm_in(struct hfc_multi *c, int which, unsigned short addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned char res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) vpm_write_address(c, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) cpld_set_reg(c, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) cpld_set_reg(c, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) enablepcibridge(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) res = readpcibridge(c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) disablepcibridge(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) cpld_set_reg(c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) vpm_out(struct hfc_multi *c, int which, unsigned short addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) vpm_write_address(c, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) enablepcibridge(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) cpld_set_reg(c, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) cpld_set_reg(c, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) writepcibridge(c, 1, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) cpld_set_reg(c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) disablepcibridge(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) unsigned char regin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) regin = vpm_in(c, which, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (regin != data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) "0x%x\n", data, addr, regin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) vpm_init(struct hfc_multi *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) unsigned char reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) unsigned int i, x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) unsigned int ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) for (x = 0; x < NUM_EC; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Setup GPIO's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ver = vpm_in(wc, x, 0x1a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) for (y = 0; y < 4; y++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* Setup TDM path - sets fsync and tdm_clk as inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) reg = vpm_in(wc, x, 0x1a3); /* misc_con */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) vpm_out(wc, x, 0x1a3, reg & ~2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* Setup Echo length (256 taps) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) vpm_out(wc, x, 0x022, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) vpm_out(wc, x, 0x023, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* Setup timeslots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) vpm_out(wc, x, 0x02f, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) mask = 0x02020202 << (x * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Setup the tdm channel masks for all chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* Setup convergence rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) printk(KERN_DEBUG "VPM: A-law mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) reg = 0x00 | 0x10 | 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) vpm_out(wc, x, 0x20, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) vpm_out(wc, x, 0x24, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) reg = vpm_in(wc, x, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /* Initialize echo cans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) for (i = 0; i < MAX_TDM_CHAN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (mask & (0x00000001 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) vpm_out(wc, x, i, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * ARM arch at least disallows a udelay of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * more than 2ms... it gives a fake "__bad_udelay"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * reference at link-time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * long delays in kernel code are pretty sucky anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * for now work around it using 5 x 2ms instead of 1 x 10ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) udelay(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) udelay(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) udelay(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) udelay(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) udelay(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /* Put in bypass mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) for (i = 0; i < MAX_TDM_CHAN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (mask & (0x00000001 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) vpm_out(wc, x, i, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* Enable bypass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) for (i = 0; i < MAX_TDM_CHAN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (mask & (0x00000001 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) vpm_out(wc, x, 0x78 + i, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) #ifdef UNUSED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) vpm_check(struct hfc_multi *hctmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) unsigned char gpi2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) gpi2 = HFC_inb(hctmp, R_GPI_IN2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if ((gpi2 & 0x3) != 0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) #endif /* UNUSED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * Interface to enable/disable the HW Echocan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * these functions are called within a spin_lock_irqsave on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * the channel instance lock, so we are not disturbed by irqs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * we can later easily change the interface to make other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * things configurable, for now we configure the taps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) vpm_echocan_on(struct hfc_multi *hc, int ch, int taps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) unsigned int timeslot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) unsigned int unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct bchannel *bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) #ifdef TXADJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int txadj = -4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (hc->chan[ch].protocol != ISDN_P_B_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (!bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) #ifdef TXADJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) sizeof(int), &txadj, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) recv_Bchannel_skb(bch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) unit = ch % 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) taps, timeslot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) vpm_out(hc, unit, timeslot, 0x7e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) vpm_echocan_off(struct hfc_multi *hc, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) unsigned int timeslot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) unsigned int unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct bchannel *bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) #ifdef TXADJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int txadj = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (hc->chan[ch].protocol != ISDN_P_B_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) #ifdef TXADJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) sizeof(int), &txadj, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) recv_Bchannel_skb(bch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) unit = ch % 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) timeslot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* FILLME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) vpm_out(hc, unit, timeslot, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * Speech Design resync feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * NOTE: This is called sometimes outside interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * We must lock irqsave, so no other interrupt (other card) will occur!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * Also multiple interrupts may nest, so must lock each access (lists, card)!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct hfc_multi *hc, *next, *pcmmaster = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) void __iomem *plx_acc_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) u_int pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) spin_lock_irqsave(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spin_lock(&plx_lock); /* must be locked inside other locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) __func__, syncmaster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* select new master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (newmaster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) printk(KERN_DEBUG "using provided controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) list_for_each_entry_safe(hc, next, &HFClist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (hc->syncronized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) newmaster = hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* Disable sync of all cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) list_for_each_entry_safe(hc, next, &HFClist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pv &= ~PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) pcmmaster = hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) "Schedule SYNC_I\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) hc->e1_resync |= 1; /* get SYNC_I */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (newmaster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) hc = newmaster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) printk(KERN_DEBUG "id=%d (0x%p) = syncronized with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) "interface.\n", hc->id, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* Enable new sync master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) pv |= PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /* switch to jatt PLL, if not disabled by RX_SYNC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (hc->ctype == HFC_TYPE_E1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) printk(KERN_DEBUG "Schedule jatt PLL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) hc->e1_resync |= 2; /* switch to jatt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (pcmmaster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) hc = pcmmaster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) "id=%d (0x%p) = PCM master syncronized "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) "with QUARTZ\n", hc->id, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* Use the crystal clock for the PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) master card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) "Schedule QUARTZ for HFC-E1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) hc->e1_resync |= 4; /* switch quartz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) "QUARTZ is automatically "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) "enabled by HFC-%dS\n", hc->ctype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) pv |= PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (!rm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) printk(KERN_ERR "%s no pcm master, this MUST "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) "not happen!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) syncmaster = newmaster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) spin_unlock(&plx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) spin_unlock_irqrestore(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* This must be called AND hc must be locked irqsave!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) plxsd_checksync(struct hfc_multi *hc, int rm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (hc->syncronized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (syncmaster == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) printk(KERN_DEBUG "%s: GOT sync on card %d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) " (id=%d)\n", __func__, hc->id + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) hfcmulti_resync(hc, hc, rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (syncmaster == hc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) printk(KERN_DEBUG "%s: LOST sync on card %d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) " (id=%d)\n", __func__, hc->id + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) hfcmulti_resync(hc, NULL, rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * free hardware resources used by driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) release_io_hfcmulti(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) void __iomem *plx_acc_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) u_int pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) u_long plx_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) printk(KERN_DEBUG "%s: entered\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /* soft reset also masks all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) hc->hw.r_cirm |= V_SRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) hc->hw.r_cirm &= ~V_SRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) udelay(1000); /* instead of 'wait' that may cause locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* release Speech Design card, if PLX was initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) printk(KERN_DEBUG "%s: release PLXSD card %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) __func__, hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) writel(PLX_GPIOC_INIT, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* Termination off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) pv &= ~PLX_TERM_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* Disconnect the PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) pv |= PLX_SLAVE_EN_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) pv &= ~PLX_MASTER_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) pv &= ~PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /* Put the DSP in Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) pv &= ~PLX_DSP_RES_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* disable memory mapped ports / io ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (hc->pci_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (hc->pci_membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) iounmap(hc->pci_membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (hc->plx_membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) iounmap(hc->plx_membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (hc->pci_iobase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) release_region(hc->pci_iobase, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (hc->xhfc_membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) iounmap((void *)hc->xhfc_membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (hc->pci_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) pci_set_drvdata(hc->pci_dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) printk(KERN_DEBUG "%s: done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * function called to reset the HFC chip. A complete software reset of chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * and fifos is done. All configuration of the chip is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) init_chip(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) u_long flags, val, val2 = 0, rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) u_char r_conf_en, rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) void __iomem *plx_acc_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) u_int pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) u_long plx_flags, hfc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) int plx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) struct hfc_multi *pos, *next, *plx_last_hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /* reset all registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) memset(&hc->hw, 0, sizeof(struct hfcm_hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* revision check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) printk(KERN_DEBUG "%s: entered\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) val = HFC_inb(hc, R_CHIP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) (val >> 1) != 0x31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) rev = HFC_inb(hc, R_CHIP_RV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) " (old FIFO handling)" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) "HFC_multi: NOTE: Your chip is revision 0, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) "ask Cologne Chip for update. Newer chips "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) "have a better FIFO handling. Old chips "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) "still work but may have slightly lower "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) "HDLC transmit performance.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (rev > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) "consider chip revision = %ld. The chip / "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) "bridge may not work.\n", rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /* set s-ram size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) hc->Flen = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) hc->Zmin = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) hc->Zlen = 384;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) hc->DTMFbase = 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) printk(KERN_DEBUG "%s: changing to 128K external RAM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) hc->hw.r_ctrl |= V_EXT_RAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) hc->hw.r_ram_sz = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) hc->Flen = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) hc->Zmin = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) hc->Zlen = 1856;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) hc->DTMFbase = 0x2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) printk(KERN_DEBUG "%s: changing to 512K external RAM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) hc->hw.r_ctrl |= V_EXT_RAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) hc->hw.r_ram_sz = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) hc->Flen = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) hc->Zmin = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) hc->Zlen = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) hc->DTMFbase = 0x2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (hc->ctype == HFC_TYPE_XHFC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) hc->Flen = 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) hc->Zmin = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) hc->Zlen = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) hc->DTMFbase = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) hc->max_trans = poll << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (hc->max_trans > hc->Zlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) hc->max_trans = hc->Zlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* Speech Design PLX bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) printk(KERN_DEBUG "%s: initializing PLXSD card %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) __func__, hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) writel(PLX_GPIOC_INIT, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* The first and the last cards are terminating the PCM bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) pv |= PLX_TERM_ON; /* hc is currently the last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Disconnect the PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pv |= PLX_SLAVE_EN_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) pv &= ~PLX_MASTER_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) pv &= ~PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Put the DSP in Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) pv &= ~PLX_DSP_RES_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * If we are the 3rd PLXSD card or higher, we must turn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * termination of last PLXSD card off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) spin_lock_irqsave(&HFClock, hfc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) plx_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) plx_last_hc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) list_for_each_entry_safe(pos, next, &HFClist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) plx_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (pos != hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) plx_last_hc = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (plx_count >= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) printk(KERN_DEBUG "%s: card %d is between, so "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) "we disable termination\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) __func__, plx_last_hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) pv &= ~PLX_TERM_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) "%s: term off: PLX_GPIO=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) spin_unlock_irqrestore(&HFClock, hfc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) /* we only want the real Z2 read-pointer for revision > 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (!test_bit(HFC_CHIP_REVISION0, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) hc->hw.r_ram_sz |= V_FZ_MD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /* select pcm mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) printk(KERN_DEBUG "%s: setting PCM into slave mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) printk(KERN_DEBUG "%s: setting PCM into master mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) hc->hw.r_pcm_md0 |= V_PCM_MD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) printk(KERN_DEBUG "%s: performing PCM auto detect\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) /* soft reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) HFC_outb(hc, 0x0C /* R_FIFO_THRES */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 0x11 /* 16 Bytes TX/RX */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) HFC_outb(hc, R_FIFO_MD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) | V_RLD_EPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) hc->hw.r_cirm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (hc->ctype != HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /* Speech Design PLX bridge pcm and sync mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* Connect PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (hc->hw.r_pcm_md0 & V_PCM_MD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) pv |= PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) pv &= ~PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) /* PCM setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (hc->slots == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) HFC_outb(hc, R_PCM_MD1, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (hc->slots == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) HFC_outb(hc, R_PCM_MD1, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (hc->slots == 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) HFC_outb(hc, R_PCM_MD1, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) else if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) HFC_outb_nodebug(hc, R_SLOT, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) HFC_outb_nodebug(hc, A_SL_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (hc->ctype != HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) HFC_outb_nodebug(hc, A_CONF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) hc->slot_owner[i] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) /* set clock speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) "%s: setting double clock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /* B410P GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) printk(KERN_NOTICE "Setting GPIOs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) HFC_outb(hc, R_GPIO_SEL, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) HFC_outb(hc, R_GPIO_EN1, 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) printk(KERN_NOTICE "calling vpm_init\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) vpm_init(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) /* check if R_F0_CNT counts (8 kHz frame count) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) val = HFC_inb(hc, R_F0_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) val += HFC_inb(hc, R_F0_CNTH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) "HFC_multi F0_CNT %ld after reset\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) set_current_state(TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) schedule_timeout((HZ / 100) ? : 1); /* Timeout minimum 10ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) val2 = HFC_inb(hc, R_F0_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) val2 += HFC_inb(hc, R_F0_CNTH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) "HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (val2 >= val + 8) { /* 1 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* it counts, so we keep the pcm mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) printk(KERN_INFO "controller is PCM bus MASTER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) printk(KERN_INFO "controller is PCM bus SLAVE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) printk(KERN_INFO "controller is PCM bus SLAVE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) "(auto detected)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /* does not count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) controller_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) printk(KERN_ERR "HFC_multi ERROR, getting no 125us "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) "pulse. Seems that controller fails.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) printk(KERN_INFO "controller is PCM bus SLAVE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) "(ignoring missing PCM clock)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /* only one pcm master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) && plxsd_master) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) printk(KERN_ERR "HFC_multi ERROR, no clock "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) "on another Speech Design card found. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) "Please be sure to connect PCM cable.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) /* retry with master clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) pv |= PLX_SYNC_O_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) printk(KERN_DEBUG "%s: master: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) "PLX_GPIO=%x\n", __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) hc->hw.r_pcm_md0 |= V_PCM_MD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) set_current_state(TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) schedule_timeout((HZ / 100) ?: 1); /* Timeout min. 10ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) val2 = HFC_inb(hc, R_F0_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) val2 += HFC_inb(hc, R_F0_CNTH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) printk(KERN_DEBUG "HFC_multi F0_CNT %ld after "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) "10 ms (2nd try)\n", val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (val2 >= val + 8) { /* 1 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) test_and_set_bit(HFC_CHIP_PCM_MASTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) printk(KERN_INFO "controller is PCM bus MASTER "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) "(auto detected)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) goto controller_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* Release the DSP Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) plxsd_master = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) plx_acc_32 = hc->plx_membase + PLX_GPIOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) pv = readl(plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) pv |= PLX_DSP_RES_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) writel(pv, plx_acc_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) __func__, pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /* pcm id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (hc->pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) printk(KERN_INFO "controller has given PCM BUS ID %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) hc->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) PCM_cnt++; /* SD has proprietary bridging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) hc->pcm = PCM_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) printk(KERN_INFO "controller has PCM BUS ID %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) "(auto selected)\n", hc->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) /* set up timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) HFC_outb(hc, R_TI_WD, poll_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) hc->hw.r_irqmsk_misc |= V_TI_IRQMSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /* set E1 state machine IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (hc->ctype == HFC_TYPE_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) hc->hw.r_irqmsk_misc |= V_STA_IRQMSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /* set DTMF detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (test_bit(HFC_CHIP_DTMF, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) printk(KERN_DEBUG "%s: enabling DTMF detection "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) "for all B-channel\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (test_bit(HFC_CHIP_ULAW, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) hc->hw.r_dtmf |= V_ULAW_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) HFC_outb(hc, R_DTMF_N, 102 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) /* conference engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (test_bit(HFC_CHIP_ULAW, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) r_conf_en = V_CONF_EN | V_ULAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) r_conf_en = V_CONF_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (hc->ctype != HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) HFC_outb(hc, R_CONF_EN, r_conf_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* setting leds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) switch (hc->leds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) case 1: /* HFC-E1 OEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) HFC_outb(hc, R_GPIO_SEL, 0x32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) HFC_outb(hc, R_GPIO_SEL, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) HFC_outb(hc, R_GPIO_EN1, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) HFC_outb(hc, R_GPIO_OUT1, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) case 2: /* HFC-4S OEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) HFC_outb(hc, R_GPIO_SEL, 0xf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) HFC_outb(hc, R_GPIO_EN1, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) HFC_outb(hc, R_GPIO_OUT1, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /* set master clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (hc->masterclk >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) printk(KERN_DEBUG "%s: setting ST master clock "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) "to port %d (0..%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) __func__, hc->masterclk, hc->ports - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /* setting misc irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) hc->hw.r_irqmsk_misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) /* RAM access test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) HFC_outb(hc, R_RAM_ADDR0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) HFC_outb(hc, R_RAM_ADDR1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) HFC_outb(hc, R_RAM_ADDR2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) HFC_outb_nodebug(hc, R_RAM_DATA, ((i * 3) & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) HFC_inb_nodebug(hc, R_RAM_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) rval = HFC_inb_nodebug(hc, R_INT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (rval != ((i * 3) & 0xff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) "addr:%x val:%x should:%x\n", i, rval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) (i * 3) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) err++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) printk(KERN_DEBUG "aborting - %d RAM access errors\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) printk(KERN_DEBUG "%s: done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * control the watchdog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) hfcmulti_watchdog(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) hc->wdcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (hc->wdcount > 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) hc->wdcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) V_GPIO_OUT3 : V_GPIO_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * output leds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) hfcmulti_leds(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) unsigned long lled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) unsigned long leddw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) int i, state, active, leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) int led[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) switch (hc->leds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) case 1: /* HFC-E1 OEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /* 2 red steady: LOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) * 1 red steady: L1 not active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) * 2 green steady: L1 active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) * 1st green flashing: activity on TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) * 2nd green flashing: activity on RX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) led[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) led[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) led[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) led[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) dch = hc->chan[hc->dnum[0]].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (hc->chan[hc->dnum[0]].los)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) led[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (hc->e1_state != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) led[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) hc->flash[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) hc->flash[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) led[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) led[3] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (!hc->flash[2] && hc->activity_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) hc->flash[2] = poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (!hc->flash[3] && hc->activity_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) hc->flash[3] = poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (hc->flash[2] && hc->flash[2] < 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) led[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (hc->flash[3] && hc->flash[3] < 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) led[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (hc->flash[2] >= 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) hc->flash[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (hc->flash[3] >= 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) hc->flash[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (hc->flash[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) hc->flash[2] += poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (hc->flash[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) hc->flash[3] += poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) /* leds are inverted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (leds != (int)hc->ledstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) HFC_outb_nodebug(hc, R_GPIO_OUT1, leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) hc->ledstate = leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) case 2: /* HFC-4S OEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /* red steady: PH_DEACTIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * green steady: PH_ACTIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) * green flashing: activity on TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) active = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) dch = hc->chan[(i << 2) | 2].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) state = dch->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (dch->dev.D.protocol == ISDN_P_NT_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) active = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) active = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (state == active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) led[i] = 1; /* led green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) hc->activity_tx |= hc->activity_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (!hc->flash[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) (hc->activity_tx & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) hc->flash[i] = poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (hc->flash[i] && hc->flash[i] < 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) led[i] = 0; /* led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) if (hc->flash[i] >= 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) hc->flash[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (hc->flash[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) hc->flash[i] += poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) led[i] = 2; /* led red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) hc->flash[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) led[i] = 0; /* led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) leds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (led[i] == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) /*green*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) leds |= (0x2 << (i * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) } else if (led[i] == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) /*red*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) leds |= (0x1 << (i * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (leds != (int)hc->ledstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) vpm_out(hc, 0, 0x1a8 + 3, leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) hc->ledstate = leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) ((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) ((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) ((led[0] & 1) << 6) | ((led[2] & 1) << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (leds != (int)hc->ledstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) hc->ledstate = leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) case 3: /* HFC 1S/2S Beronet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) /* red steady: PH_DEACTIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) * green steady: PH_ACTIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) * green flashing: activity on TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) active = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) dch = hc->chan[(i << 2) | 2].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) state = dch->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (dch->dev.D.protocol == ISDN_P_NT_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) active = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) active = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (state == active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) led[i] = 1; /* led green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) hc->activity_tx |= hc->activity_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (!hc->flash[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) (hc->activity_tx & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) hc->flash[i] = poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (hc->flash[i] < 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) led[i] = 0; /* led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (hc->flash[i] >= 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) hc->flash[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (hc->flash[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) hc->flash[i] += poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) led[i] = 2; /* led red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) hc->flash[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) led[i] = 0; /* led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) | ((led[1]&1) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (leds != (int)hc->ledstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) HFC_outb_nodebug(hc, R_GPIO_EN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) HFC_outb_nodebug(hc, R_GPIO_OUT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) hc->ledstate = leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) case 8: /* HFC 8S+ Beronet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) /* off: PH_DEACTIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * steady: PH_ACTIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) * flashing: activity on TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) lled = 0xff; /* leds off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) active = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) dch = hc->chan[(i << 2) | 2].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) state = dch->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (dch->dev.D.protocol == ISDN_P_NT_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) active = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) active = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (state == active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) lled &= ~(1 << i); /* led on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) hc->activity_tx |= hc->activity_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (!hc->flash[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) (hc->activity_tx & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) hc->flash[i] = poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (hc->flash[i] < 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) lled |= 1 << i; /* led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (hc->flash[i] >= 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) hc->flash[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (hc->flash[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) hc->flash[i] += poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) hc->flash[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) leddw = lled << 24 | lled << 16 | lled << 8 | lled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (leddw != hc->ledstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) /* HFC_outb(hc, R_BRG_PCM_CFG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) /* was _io before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) outw(0x4000, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) outl(leddw, hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) hc->ledstate = leddw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) hc->activity_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) hc->activity_rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * read dtmf coefficients
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) hfcmulti_dtmf(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) s32 *coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) u_int mantissa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) int co, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) struct bchannel *bch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) u8 exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) int dtmf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) u16 w_float;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) struct mISDNhead *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (debug & DEBUG_HFCMULTI_DTMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) for (ch = 0; ch <= 31; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) /* only process enabled B-channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (!bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (!hc->created[hc->chan[ch].port])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (debug & DEBUG_HFCMULTI_DTMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) printk(KERN_DEBUG "%s: dtmf channel %d:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) __func__, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) dtmf = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) for (co = 0; co < 8; co++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) /* read W(n-1) coefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) addr = hc->DTMFbase + ((co << 7) | (ch << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) HFC_outb_nodebug(hc, R_RAM_ADDR0, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) HFC_outb_nodebug(hc, R_RAM_ADDR1, addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) | V_ADDR_INC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (debug & DEBUG_HFCMULTI_DTMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) printk(" %04x", w_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) /* decode float (see chip doc) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) mantissa = w_float & 0x0fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (w_float & 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) mantissa |= 0xfffff000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) exponent = (w_float >> 12) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (exponent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) mantissa ^= 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) mantissa <<= (exponent - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) /* store coefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) coeff[co << 1] = mantissa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) /* read W(n) coefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (debug & DEBUG_HFCMULTI_DTMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) printk(" %04x", w_float);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) /* decode float (see chip doc) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) mantissa = w_float & 0x0fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (w_float & 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) mantissa |= 0xfffff000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) exponent = (w_float >> 12) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (exponent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) mantissa ^= 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) mantissa <<= (exponent - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) /* store coefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) coeff[(co << 1) | 1] = mantissa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (debug & DEBUG_HFCMULTI_DTMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) printk(" DTMF ready %08x %08x %08x %08x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) "%08x %08x %08x %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) coeff[0], coeff[1], coeff[2], coeff[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) coeff[4], coeff[5], coeff[6], coeff[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) hc->chan[ch].coeff_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if (hc->chan[ch].coeff_count == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) hc->chan[ch].coeff_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) skb = mI_alloc_skb(512, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) printk(KERN_DEBUG "%s: No memory for skb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) hh->prim = PH_CONTROL_IND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) hh->id = DTMF_HFC_COEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) skb_put_data(skb, hc->chan[ch].coeff, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) recv_Bchannel_skb(bch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) /* restart DTMF processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) hc->dtmf = dtmf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (dtmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) * fill fifo as much as possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) hfcmulti_tx(struct hfc_multi *hc, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) int i, ii, temp, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) int Zspace, z1, z2; /* must be int for calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) int Fspace, f1, f2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) u_char *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) int *txpending, slot_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) struct sk_buff **sp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) int *idxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) dch = hc->chan[ch].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if ((!dch) && (!bch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) txpending = &hc->chan[ch].txpending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) slot_tx = hc->chan[ch].slot_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (!test_bit(FLG_ACTIVE, &dch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) sp = &dch->tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) idxp = &dch->tx_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (!test_bit(FLG_ACTIVE, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) sp = &bch->tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) idxp = &bch->tx_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) if (*sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) len = (*sp)->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if ((!len) && *txpending != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return; /* no data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) (hc->chan[ch].slot_rx < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) (hc->chan[ch].slot_tx < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) HFC_outb_nodebug(hc, R_FIFO, ch << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (*txpending == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /* reset fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) *txpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) next_frame:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) f1 = HFC_inb_nodebug(hc, A_F1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) f2 = HFC_inb_nodebug(hc, A_F2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) "%s(card %d): reread f2 because %d!=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) __func__, hc->id + 1, temp, f2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) f2 = temp; /* repeat until F2 is equal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) Fspace = f2 - f1 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (Fspace < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) Fspace += hc->Flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) * Old FIFO handling doesn't give us the current Z2 read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * pointer, so we cannot send the next frame before the fifo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * is empty. It makes no difference except for a slightly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) * lower performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) if (f1 != f2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) Fspace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) Fspace = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) /* one frame only for ST D-channels, to allow resending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (hc->ctype != HFC_TYPE_E1 && dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) if (f1 != f2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) Fspace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) /* F-counter full condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (Fspace == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) printk(KERN_DEBUG "%s(card %d): reread z2 because "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) "%d!=%d\n", __func__, hc->id + 1, temp, z2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) z2 = temp; /* repeat unti Z2 is equal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) hc->chan[ch].Zfill = z1 - z2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (hc->chan[ch].Zfill < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) hc->chan[ch].Zfill += hc->Zlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) Zspace = z2 - z1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) if (Zspace <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) Zspace += hc->Zlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) Zspace -= 4; /* keep not too full, so pointers will not overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) /* fill transparent data only to maxinum transparent load (minus 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) Zspace = Zspace - hc->Zlen + hc->max_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (Zspace <= 0) /* no space of 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) /* if no data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) if (z1 == z2) { /* empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) /* if done with FIFO audio data during PCM connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) *txpending && slot_tx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) "%s: reconnecting PCM due to no "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) "more FIFO data: channel %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) "slot_tx %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) __func__, ch, slot_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /* connect slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) HFC_outb(hc, A_CON_HDLC, 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) | 0x07 << 2 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /* Enable FIFO, no interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) HFC_outb(hc, A_CON_HDLC, 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) | 0x07 << 2 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) /* Enable FIFO, no interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) HFC_outb_nodebug(hc, R_FIFO, ch << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) *txpending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) return; /* no data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) /* "fill fifo if empty" feature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (debug & DEBUG_HFCMULTI_FILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) printk(KERN_DEBUG "%s: buffer empty, so we have "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) "underrun\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /* fill buffer, to prevent future underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) hc->write_fifo(hc, hc->silence_data, poll >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) Zspace -= (poll >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) /* if audio data and connected slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) && slot_tx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) printk(KERN_DEBUG "%s: disconnecting PCM due to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) "FIFO data: channel %d slot_tx %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) __func__, ch, slot_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) /* disconnect slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) HFC_outb(hc, A_CON_HDLC, 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) | 0x07 << 2 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) /* Enable FIFO, no interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) HFC_outb(hc, A_CON_HDLC, 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) | 0x07 << 2 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) /* Enable FIFO, no interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) HFC_outb_nodebug(hc, R_FIFO, ch << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) *txpending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) /* show activity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) if (dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) hc->activity_tx |= 1 << hc->chan[ch].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) /* fill fifo to what we have left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) ii = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (dch || test_bit(FLG_HDLC, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) temp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) i = *idxp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) d = (*sp)->data + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (ii - i > Zspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) ii = Zspace + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) temp ? "HDLC" : "TRANS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) /* Have to prep the audio data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) hc->write_fifo(hc, d, ii - i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) hc->chan[ch].Zfill += ii - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) *idxp = ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) /* if not all data has been written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (ii != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) /* NOTE: fifo is started by the calling function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) /* if all data has been written, terminate frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) /* increment f-counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) dev_kfree_skb(*sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) /* check for next frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (bch && get_next_bframe(bch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) len = (*sp)->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) goto next_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (dch && get_next_dframe(dch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) len = (*sp)->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) goto next_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) * now we have no more data, so in case of transparent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) * we set the last byte in fifo to 'silence' in case we will get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) * no more data at all. this prevents sending an undefined value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) /* NOTE: only called if E1 card is in active state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) hfcmulti_rx(struct hfc_multi *hc, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) int f1 = 0, f2 = 0; /* = 0, to make GCC happy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) int again = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) struct dchannel *dch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) struct sk_buff *skb, **sp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) int maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (!test_bit(FLG_ACTIVE, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) } else if (hc->chan[ch].dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) dch = hc->chan[ch].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (!test_bit(FLG_ACTIVE, &dch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) next_frame:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) /* on first AND before getting next valid frame, R_FIFO must be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) to. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) (hc->chan[ch].slot_rx < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) (hc->chan[ch].slot_tx < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) /* ignore if rx is off BUT change fifo (above) to start pending TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) if (hc->chan[ch].rx_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) bch->dropcnt += poll; /* not exact but fair enough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) f1 = HFC_inb_nodebug(hc, A_F1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) "%s(card %d): reread f1 because %d!=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) __func__, hc->id + 1, temp, f1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) f1 = temp; /* repeat until F1 is equal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) f2 = HFC_inb_nodebug(hc, A_F2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) printk(KERN_DEBUG "%s(card %d): reread z2 because "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) "%d!=%d\n", __func__, hc->id + 1, temp, z2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) z1 = temp; /* repeat until Z1 is equal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) Zsize = z1 - z2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) /* complete hdlc frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) Zsize++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) if (Zsize < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) Zsize += hc->Zlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /* if buffer is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) if (Zsize <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) if (bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) maxlen = bchannel_get_rxbuf(bch, Zsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (maxlen < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) pr_warn("card%d.B%d: No bufferspace for %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) hc->id + 1, bch->nr, Zsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) sp = &bch->rx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) maxlen = bch->maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) } else { /* Dchannel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) sp = &dch->rx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) maxlen = dch->maxlen + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (*sp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) *sp = mI_alloc_skb(maxlen, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) if (*sp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) pr_warn("card%d: No mem for dch rx_skb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) /* show activity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) if (dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) hc->activity_rx |= 1 << hc->chan[ch].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) /* empty fifo with what we have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) "got=%d (again %d)\n", __func__, hc->id + 1, ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) f1, f2, Zsize + (*sp)->len, again);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) /* HDLC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if ((Zsize + (*sp)->len) > maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) "%s(card %d): hdlc-frame too large.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) __func__, hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) skb_trim(*sp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) if (f1 != f2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) /* increment Z2,F2-counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) /* check size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if ((*sp)->len < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) "%s(card %d): Frame below minimum "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) "size\n", __func__, hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) skb_trim(*sp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) goto next_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) /* there is at least one complete frame, check crc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if ((*sp)->data[(*sp)->len - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) if (debug & DEBUG_HFCMULTI_CRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) "%s: CRC-error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) skb_trim(*sp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) goto next_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) skb_trim(*sp, (*sp)->len - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) if ((*sp)->len < MISDN_COPY_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) skb = *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) *sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if (*sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) skb_put_data(*sp, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) skb_trim(skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) printk(KERN_DEBUG "%s: No mem\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) *sp = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) if (debug & DEBUG_HFCMULTI_FIFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) printk(KERN_DEBUG "%s(card %d):",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) __func__, hc->id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) while (temp < (*sp)->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) printk(" %02x", (*sp)->data[temp++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) if (dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) recv_Dchannel(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) recv_Bchannel(bch, MISDN_ID_ANY, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) *sp = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) again++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) goto next_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) /* there is an incomplete frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) /* transparent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if (debug & DEBUG_HFCMULTI_FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) "%s(card %d): fifo(%d) reading %d bytes "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) "(z1=%04x, z2=%04x) TRANS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) __func__, hc->id + 1, ch, Zsize, z1, z2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) /* only bch is transparent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) recv_Bchannel(bch, hc->chan[ch].Zfill, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) * Interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) signal_state_up(struct dchannel *dch, int info, char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) int id, data = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) printk(KERN_DEBUG "%s: %s\n", __func__, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) recv_Dchannel_skb(dch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) handle_timer_irq(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) int ch, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) /* process queued resync jobs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) if (hc->e1_resync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) /* lock, so e1_resync gets not changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) spin_lock_irqsave(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) if (hc->e1_resync & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) printk(KERN_DEBUG "Enable SYNC_I\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) /* disable JATT, if RX_SYNC is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) if (hc->e1_resync & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) printk(KERN_DEBUG "Enable jatt PLL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (hc->e1_resync & 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) if (debug & DEBUG_HFCMULTI_PLXSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) "Enable QUARTZ for HFC-E1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) /* set jatt to quartz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) | V_JATT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) /* switch to JATT, in case it is not already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) HFC_outb(hc, R_SYNC_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) hc->e1_resync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) spin_unlock_irqrestore(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) for (ch = 0; ch <= 31; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) if (hc->created[hc->chan[ch].port]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) hfcmulti_tx(hc, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) /* fifo is started when switching to rx-fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) hfcmulti_rx(hc, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) if (hc->chan[ch].dch &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) hc->chan[ch].nt_timer > -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) dch = hc->chan[ch].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) if (!(--hc->chan[ch].nt_timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) schedule_event(dch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) FLG_PHCHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) if (debug &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) "%s: nt_timer at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) "state %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) dch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) dch = hc->chan[hc->dnum[0]].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) /* LOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) hc->chan[hc->dnum[0]].los = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (!temp && hc->chan[hc->dnum[0]].los)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) signal_state_up(dch, L1_SIGNAL_LOS_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) "LOS detected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) if (temp && !hc->chan[hc->dnum[0]].los)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) signal_state_up(dch, L1_SIGNAL_LOS_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) "LOS gone");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) /* AIS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) if (!temp && hc->chan[hc->dnum[0]].ais)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) signal_state_up(dch, L1_SIGNAL_AIS_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) "AIS detected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) if (temp && !hc->chan[hc->dnum[0]].ais)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) signal_state_up(dch, L1_SIGNAL_AIS_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) "AIS gone");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) hc->chan[hc->dnum[0]].ais = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) /* SLIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) if (!temp && hc->chan[hc->dnum[0]].slip_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) signal_state_up(dch, L1_SIGNAL_SLIP_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) " bit SLIP detected RX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) hc->chan[hc->dnum[0]].slip_rx = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) if (!temp && hc->chan[hc->dnum[0]].slip_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) signal_state_up(dch, L1_SIGNAL_SLIP_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) " bit SLIP detected TX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) hc->chan[hc->dnum[0]].slip_tx = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /* RDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (!temp && hc->chan[hc->dnum[0]].rdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) signal_state_up(dch, L1_SIGNAL_RDI_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) "RDI detected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) if (temp && !hc->chan[hc->dnum[0]].rdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) signal_state_up(dch, L1_SIGNAL_RDI_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) "RDI gone");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) hc->chan[hc->dnum[0]].rdi = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) temp = HFC_inb_nodebug(hc, R_JATT_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) switch (hc->chan[hc->dnum[0]].sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) if ((temp & 0x60) == 0x60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) if (debug & DEBUG_HFCMULTI_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) "%s: (id=%d) E1 now "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) "in clock sync\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) __func__, hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) HFC_outb(hc, R_RX_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) HFC_outb(hc, R_TX_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) hc->chan[hc->dnum[0]].sync = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) goto check_framesync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) if ((temp & 0x60) != 0x60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (debug & DEBUG_HFCMULTI_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) "%s: (id=%d) E1 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) "lost clock sync\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) __func__, hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) hc->chan[hc->dnum[0]].sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) check_framesync:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) temp = HFC_inb_nodebug(hc, R_SYNC_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (temp == 0x27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) if (debug & DEBUG_HFCMULTI_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) "%s: (id=%d) E1 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) "now in frame sync\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) __func__, hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) hc->chan[hc->dnum[0]].sync = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) if ((temp & 0x60) != 0x60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) if (debug & DEBUG_HFCMULTI_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) "%s: (id=%d) E1 lost "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) "clock & frame sync\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) __func__, hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) hc->chan[hc->dnum[0]].sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) temp = HFC_inb_nodebug(hc, R_SYNC_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) if (temp != 0x27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) if (debug & DEBUG_HFCMULTI_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) "%s: (id=%d) E1 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) "lost frame sync\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) __func__, hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) hc->chan[hc->dnum[0]].sync = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) hfcmulti_watchdog(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (hc->leds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) hfcmulti_leds(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) int ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) u_char st_status, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) /* state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) for (ch = 0; ch <= 31; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (hc->chan[ch].dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) dch = hc->chan[ch].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) if (r_irq_statech & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) HFC_outb_nodebug(hc, R_ST_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) /* undocumented: status changes during read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) while (st_status != (temp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) printk(KERN_DEBUG "%s: reread "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) "STATE because %d!=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) __func__, temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) st_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) st_status = temp; /* repeat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) /* Speech Design TE-sync indication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) if (test_bit(HFC_CHIP_PLXSD, &hc->chip) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) dch->dev.D.protocol == ISDN_P_TE_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (st_status & V_FR_SYNC_ST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) hc->syncronized |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) (1 << hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) hc->syncronized &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) ~(1 << hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) dch->state = st_status & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) if (dch->dev.D.protocol == ISDN_P_NT_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) active = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) active = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (dch->state == active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) HFC_outb_nodebug(hc, R_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) HFC_outb_nodebug(hc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) dch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) schedule_event(dch, FLG_PHCHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) "%s: S/T newstate %x port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) __func__, dch->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) r_irq_statech >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) plxsd_checksync(hc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) fifo_irq(struct hfc_multi *hc, int block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) int ch, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) u_char r_irq_fifo_bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) while (j < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) ch = (block << 2) + (j >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) dch = hc->chan[ch].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) j += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) if (dch && (r_irq_fifo_bl & (1 << j)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) test_bit(FLG_ACTIVE, &dch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) hfcmulti_tx(hc, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) /* start fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) HFC_outb_nodebug(hc, R_FIFO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) if (bch && (r_irq_fifo_bl & (1 << j)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) test_bit(FLG_ACTIVE, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) hfcmulti_tx(hc, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) /* start fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) HFC_outb_nodebug(hc, R_FIFO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (dch && (r_irq_fifo_bl & (1 << j)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) test_bit(FLG_ACTIVE, &dch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) hfcmulti_rx(hc, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (bch && (r_irq_fifo_bl & (1 << j)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) test_bit(FLG_ACTIVE, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) hfcmulti_rx(hc, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) #ifdef IRQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) int irqsem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) hfcmulti_interrupt(int intno, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) #ifdef IRQCOUNT_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) iq5 = 0, iq6 = 0, iqcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) struct hfc_multi *hc = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) u_char r_irq_statech, status, r_irq_misc, r_irq_oview;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) void __iomem *plx_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) u_short wval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) u_char e1_syncsta, temp, temp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) if (!hc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) printk(KERN_ERR "HFC-multi: Spurious interrupt!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) spin_lock(&hc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) #ifdef IRQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) if (irqsem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) printk(KERN_ERR "irq for card %d during irq from "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) "card %d, this is no bug.\n", hc->id + 1, irqsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) irqsem = hc->id + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) #ifdef CONFIG_MISDN_HFCMULTI_8xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) goto irq_notforus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) spin_lock_irqsave(&plx_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) plx_acc = hc->plx_membase + PLX_INTCSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) wval = readw(plx_acc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) spin_unlock_irqrestore(&plx_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) if (!(wval & PLX_INTCSR_LINTI1_STATUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) goto irq_notforus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) status = HFC_inb_nodebug(hc, R_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) #ifdef IRQCOUNT_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) if (r_irq_statech)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) iq1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) if (status & V_DTMF_STA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) iq2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (status & V_LOST_STA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) iq3++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) if (status & V_EXT_IRQSTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) iq4++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) if (status & V_MISC_IRQSTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) iq5++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) if (status & V_FR_IRQSTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) iq6++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) if (iqcnt++ > 5000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) iq1, iq2, iq3, iq4, iq5, iq6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) iqcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) if (!r_irq_statech &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) V_MISC_IRQSTA | V_FR_IRQSTA))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) /* irq is not for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) goto irq_notforus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) hc->irqcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) if (r_irq_statech) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) if (hc->ctype != HFC_TYPE_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) ph_state_irq(hc, r_irq_statech);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) if (status & V_EXT_IRQSTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) ; /* external IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) if (status & V_LOST_STA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) /* LOST IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) if (status & V_MISC_IRQSTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) /* misc IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) if (r_irq_misc & V_STA_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) /* state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) dch = hc->chan[hc->dnum[0]].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) && hc->e1_getclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) if (e1_syncsta & V_FR_SYNC_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) hc->syncronized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) hc->syncronized = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) /* undocumented: status changes during read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) temp = HFC_inb_nodebug(hc, R_E1_RD_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) while (temp != (temp2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) HFC_inb_nodebug(hc, R_E1_RD_STA))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) printk(KERN_DEBUG "%s: reread "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) "STATE because %d!=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) __func__, temp, temp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) temp = temp2; /* repeat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) /* broadcast state change to all fragments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) "%s: E1 (id=%d) newstate %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) __func__, hc->id, temp & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) for (i = 0; i < hc->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) dch = hc->chan[hc->dnum[i]].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) dch->state = temp & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) schedule_event(dch, FLG_PHCHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) plxsd_checksync(hc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) if (r_irq_misc & V_TI_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) if (hc->iclock_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) mISDN_clock_update(hc->iclock, poll, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) handle_timer_irq(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) if (r_irq_misc & V_DTMF_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) hfcmulti_dtmf(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) if (r_irq_misc & V_IRQ_PROC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) static int irq_proc_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) if (!irq_proc_cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) printk(KERN_DEBUG "%s: got V_IRQ_PROC -"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) " this should not happen\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) if (status & V_FR_IRQSTA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) /* FIFO IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (r_irq_oview & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) fifo_irq(hc, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) #ifdef IRQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) irqsem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) spin_unlock(&hc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) irq_notforus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) #ifdef IRQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) irqsem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) spin_unlock(&hc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) * timer callback for D-chan busy resolution. Currently no function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) hfcmulti_dbusy_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) * activate/deactivate hardware for selected channels and mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) * configure B-channel with the given protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) * ch eqals to the HFC-channel (0-31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) * ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) * for S/T, 1-31 for E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) * the hdlc interrupts will be set/unset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) int bank_tx, int slot_rx, int bank_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) int flow_tx = 0, flow_rx = 0, routing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) int oslot_tx, oslot_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) int conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) if (ch < 0 || ch > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) oslot_tx = hc->chan[ch].slot_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) oslot_rx = hc->chan[ch].slot_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) conf = hc->chan[ch].conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) "%s: card %d channel %d protocol %x slot old=%d new=%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) bank_tx, oslot_rx, slot_rx, bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) if (oslot_tx >= 0 && slot_tx != oslot_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) /* remove from slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) printk(KERN_DEBUG "%s: remove from slot %d (TX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) __func__, oslot_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) if (hc->slot_owner[oslot_tx << 1] == ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) HFC_outb(hc, R_SLOT, oslot_tx << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) HFC_outb(hc, A_SL_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) if (hc->ctype != HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) HFC_outb(hc, A_CONF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) hc->slot_owner[oslot_tx << 1] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) "%s: we are not owner of this tx slot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) "anymore, channel %d is.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) __func__, hc->slot_owner[oslot_tx << 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) if (oslot_rx >= 0 && slot_rx != oslot_rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) /* remove from slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) "%s: remove from slot %d (RX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) __func__, oslot_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) HFC_outb(hc, A_SL_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) hc->slot_owner[(oslot_rx << 1) | 1] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) "%s: we are not owner of this rx slot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) "anymore, channel %d is.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) hc->slot_owner[(oslot_rx << 1) | 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) if (slot_tx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) flow_tx = 0x80; /* FIFO->ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) /* disable pcm slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) hc->chan[ch].slot_tx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) hc->chan[ch].bank_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) /* set pcm slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) if (hc->chan[ch].txpending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) flow_tx = 0x80; /* FIFO->ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) flow_tx = 0xc0; /* PCM->ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) /* put on slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) routing = bank_tx ? 0xc0 : 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) if (conf >= 0 || bank_tx > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) routing = 0x40; /* loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) " %d flow %02x routing %02x conf %d (TX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) __func__, ch, slot_tx, bank_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) flow_tx, routing, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) HFC_outb(hc, R_SLOT, slot_tx << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) HFC_outb(hc, A_SL_CFG, (ch << 1) | routing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) if (hc->ctype != HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) HFC_outb(hc, A_CONF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) (conf < 0) ? 0 : (conf | V_CONF_SL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) hc->slot_owner[slot_tx << 1] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) hc->chan[ch].slot_tx = slot_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) hc->chan[ch].bank_tx = bank_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) if (slot_rx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) /* disable pcm slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) flow_rx = 0x80; /* ST->FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) hc->chan[ch].slot_rx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) hc->chan[ch].bank_rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) /* set pcm slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) if (hc->chan[ch].txpending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) flow_rx = 0x80; /* ST->FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) flow_rx = 0xc0; /* ST->(FIFO,PCM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) /* put on slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) routing = bank_rx ? 0x80 : 0xc0; /* reversed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) if (conf >= 0 || bank_rx > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) routing = 0x40; /* loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) " %d flow %02x routing %02x conf %d (RX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) __func__, ch, slot_rx, bank_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) flow_rx, routing, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) HFC_outb(hc, R_SLOT, (slot_rx << 1) | V_SL_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) HFC_outb(hc, A_SL_CFG, (ch << 1) | V_CH_DIR | routing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) hc->slot_owner[(slot_rx << 1) | 1] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) hc->chan[ch].slot_rx = slot_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) hc->chan[ch].bank_rx = bank_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) case (ISDN_P_NONE):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) /* disable TX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) HFC_outb(hc, R_FIFO, ch << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) HFC_outb(hc, A_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) /* disable RX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) HFC_outb(hc, R_FIFO, (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) HFC_outb(hc, A_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) hc->hw.a_st_ctrl0[hc->chan[ch].port] &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) HFC_outb(hc, A_ST_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) hc->hw.a_st_ctrl0[hc->chan[ch].port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) if (hc->chan[ch].bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) test_and_clear_bit(FLG_TRANSPARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) &hc->chan[ch].bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) case (ISDN_P_B_RAW): /* B-channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) if (test_bit(HFC_CHIP_B410P, &hc->chip) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) (hc->chan[ch].slot_rx < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) (hc->chan[ch].slot_tx < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) "Setting B-channel %d to echo cancelable "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) "state on PCM slot %d\n", ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) "Enabling pass through for channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) vpm_out(hc, ch, ((ch / 4) * 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) ((ch % 4) * 4) + 1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) /* rx path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) /* S/T -> PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) HFC_outb(hc, R_FIFO, (ch << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) ((ch % 4) * 4) + 1) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) /* PCM -> FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) HFC_outb(hc, A_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) if (hc->chan[ch].protocol != protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) ((ch % 4) * 4) + 1) << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) /* tx path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) /* PCM -> S/T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) HFC_outb(hc, R_FIFO, (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) ((ch % 4) * 4)) << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) /* FIFO -> PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) HFC_outb(hc, R_FIFO, 0x20 | (ch << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) HFC_outb(hc, A_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) if (hc->chan[ch].protocol != protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) /* tx silence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) ((ch % 4) * 4)) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) /* enable TX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) HFC_outb(hc, R_FIFO, ch << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) /* Enable FIFO, no interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) V_HDLC_TRP | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) HFC_outb(hc, A_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) if (hc->chan[ch].protocol != protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) /* tx silence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) /* enable RX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) HFC_outb(hc, R_FIFO, (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) V_HDLC_TRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) /* Enable FIFO, no interrupt*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) V_HDLC_TRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) HFC_outb(hc, A_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) if (hc->chan[ch].protocol != protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) if (hc->ctype != HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) HFC_outb(hc, A_ST_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) hc->hw.a_st_ctrl0[hc->chan[ch].port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) if (hc->chan[ch].bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) test_and_set_bit(FLG_TRANSPARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) &hc->chan[ch].bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) case (ISDN_P_B_HDLC): /* B-channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) case (ISDN_P_TE_S0): /* D-channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) case (ISDN_P_NT_S0):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) case (ISDN_P_TE_E1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) case (ISDN_P_NT_E1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) /* enable TX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) HFC_outb(hc, R_FIFO, ch << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) /* E1 or B-channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) HFC_outb(hc, A_SUBCH_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) /* D-Channel without HDLC fill flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) HFC_outb(hc, A_SUBCH_CFG, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) HFC_outb(hc, A_IRQ_MSK, V_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) /* enable RX fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) HFC_outb(hc, R_FIFO, (ch << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) HFC_outb(hc, A_IRQ_MSK, V_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) if (hc->chan[ch].bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) if (hc->ctype != HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) HFC_outb(hc, A_ST_CTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) hc->hw.a_st_ctrl0[hc->chan[ch].port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) printk(KERN_DEBUG "%s: protocol not known %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) __func__, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) hc->chan[ch].protocol = ISDN_P_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) hc->chan[ch].protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) * connect/disconnect PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) int slot_rx, int bank_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) /* disable PCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) /* enable pcm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) slot_rx, bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) * set/disable conference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) hfcmulti_conf(struct hfc_multi *hc, int ch, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) if (num >= 0 && num <= 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) hc->chan[ch].conf = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) hc->chan[ch].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) hc->chan[ch].bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) * set/disable sample loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) /* NOTE: this function is experimental and therefore disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) * Layer 1 callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) hfcm_l1callback(struct dchannel *dch, u_int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) struct hfc_multi *hc = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) case INFO3_P8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) case INFO3_P10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) case HW_RESET_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) /* start activation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) "%s: HW_RESET_REQ no BRI\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) udelay(6); /* wait at least 5,21us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) HFC_outb(hc, A_ST_WR_STATE, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT * 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) /* activate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) l1_event(dch->l1, HW_POWERUP_IND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) case HW_DEACT_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) /* start deactivation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) "%s: HW_DEACT_REQ no BRI\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) /* deactivate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) hc->syncronized &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) ~(1 << hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) plxsd_checksync(hc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) skb_queue_purge(&dch->squeue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) if (dch->tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) dev_kfree_skb(dch->tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) dch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) dch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) if (dch->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) dev_kfree_skb(dch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) dch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) del_timer(&dch->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) case HW_POWERUP_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) "%s: HW_POWERUP_REQ no BRI\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) udelay(6); /* wait at least 5,21us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) case PH_ACTIVATE_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) test_and_set_bit(FLG_ACTIVE, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) case PH_DEACTIVATE_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) if (dch->debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) printk(KERN_DEBUG "%s: unknown command %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) * Layer2 -> Layer 1 Transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) struct dchannel *dch = container_of(dev, struct dchannel, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) struct hfc_multi *hc = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) switch (hh->prim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) case PH_DATA_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) if (skb->len < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) ret = dchannel_senddata(dch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) if (ret > 0) { /* direct TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) id = hh->id; /* skb can be freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) hfcmulti_tx(hc, dch->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) /* start fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) HFC_outb(hc, R_FIFO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) HFC_wait(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) case PH_ACTIVATE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) if (dch->dev.D.protocol != ISDN_P_TE_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) "%s: PH_ACTIVATE port %d (0..%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) __func__, hc->chan[dch->slot].port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) hc->ports - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) /* start activation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) ph_state_change(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) "%s: E1 report state %x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) __func__, dch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) HFC_outb(hc, R_ST_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) /* G1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) udelay(6); /* wait at least 5,21us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) HFC_outb(hc, A_ST_WR_STATE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) HFC_outb(hc, A_ST_WR_STATE, 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) (V_ST_ACT * 3)); /* activate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) dch->state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) ret = l1_event(dch->l1, hh->prim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) case PH_DEACTIVATE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) if (dch->dev.D.protocol != ISDN_P_TE_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) "%s: PH_DEACTIVATE port %d (0..%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) __func__, hc->chan[dch->slot].port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) hc->ports - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) /* start deactivation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) "%s: PH_DEACTIVATE no BRI\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) HFC_outb(hc, R_ST_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) /* deactivate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) dch->state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) skb_queue_purge(&dch->squeue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) if (dch->tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) dev_kfree_skb(dch->tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) dch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) dch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) if (dch->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) dev_kfree_skb(dch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) dch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) del_timer(&dch->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) #ifdef FIXME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) dchannel_sched_event(&hc->dch, D_CLEARBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) ret = l1_event(dch->l1, hh->prim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) deactivate_bchannel(struct bchannel *bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) struct hfc_multi *hc = bch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) mISDN_clear_bchannel(bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) hc->chan[bch->slot].coeff_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) hc->chan[bch->slot].rx_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) hc->chan[bch->slot].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) struct bchannel *bch = container_of(ch, struct bchannel, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) struct hfc_multi *hc = bch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) switch (hh->prim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) case PH_DATA_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) if (!skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) ret = bchannel_senddata(bch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) if (ret > 0) { /* direct TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) hfcmulti_tx(hc, bch->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) /* start fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) HFC_outb_nodebug(hc, R_FIFO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) case PH_ACTIVATE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) __func__, bch->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) /* activate B-channel if not already activated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) hc->chan[bch->slot].txpending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) ret = mode_hfcmulti(hc, bch->slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) ch->protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) hc->chan[bch->slot].slot_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) hc->chan[bch->slot].bank_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) hc->chan[bch->slot].slot_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) hc->chan[bch->slot].bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) && test_bit(HFC_CHIP_DTMF, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) /* start decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) hc->dtmf = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) if (debug & DEBUG_HFCMULTI_DTMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) "%s: start dtmf decoder\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) HFC_outb(hc, R_DTMF, hc->hw.r_dtmf |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) V_RST_DTMF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) case PH_CONTROL_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) switch (hh->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) case HFC_SPL_LOOP_ON: /* set sample loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) "%s: HFC_SPL_LOOP_ON (len = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) __func__, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) case HFC_SPL_LOOP_OFF: /* set silence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) "%s: unknown PH_CONTROL_REQ info %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) __func__, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) case PH_DEACTIVATE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) deactivate_bchannel(bch); /* locked there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) * bchannel control function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) struct dsp_features *features =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) (struct dsp_features *)(*((u_long *)&cq->p1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) struct hfc_multi *hc = bch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) int slot_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) int bank_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) int slot_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) int bank_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) switch (cq->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) case MISDN_CTRL_GETOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) ret = mISDN_ctrl_bchannel(bch, cq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) ret = mISDN_ctrl_bchannel(bch, cq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) hc->chan[bch->slot].rx_off = !!cq->p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) if (!hc->chan[bch->slot].rx_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) /* reset fifo on rx on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) __func__, bch->nr, hc->chan[bch->slot].rx_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) case MISDN_CTRL_FILL_EMPTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) ret = mISDN_ctrl_bchannel(bch, cq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) hc->silence = bch->fill[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) memset(hc->silence_data, hc->silence, sizeof(hc->silence_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) case MISDN_CTRL_HW_FEATURES: /* fill features structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) printk(KERN_DEBUG "%s: HW_FEATURE request\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) /* create confirm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) features->hfc_id = hc->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) if (test_bit(HFC_CHIP_DTMF, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) features->hfc_dtmf = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) if (test_bit(HFC_CHIP_CONF, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) features->hfc_conf = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) features->hfc_loops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) features->hfc_echocanhw = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) features->pcm_id = hc->pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) features->pcm_slots = hc->slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) features->pcm_banks = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) slot_tx = cq->p1 & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) bank_tx = cq->p1 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) slot_rx = cq->p2 & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) bank_rx = cq->p2 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) "%s: HFC_PCM_CONN slot %d bank %d (TX) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) "slot %d bank %d (RX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) __func__, slot_tx, bank_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) slot_rx, bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) if (slot_tx < hc->slots && bank_tx <= 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) slot_rx < hc->slots && bank_rx <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) hfcmulti_pcm(hc, bch->slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) slot_tx, bank_tx, slot_rx, bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) "%s: HFC_PCM_CONN slot %d bank %d (TX) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) "slot %d bank %d (RX) out of range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) __func__, slot_tx, bank_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) slot_rx, bank_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) printk(KERN_DEBUG "%s: HFC_PCM_DISC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) num = cq->p1 & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) __func__, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) if (num <= 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) hfcmulti_conf(hc, bch->slot, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) "%s: HW_CONF_JOIN conf %d out of range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) __func__, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) hfcmulti_conf(hc, bch->slot, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) case MISDN_CTRL_HFC_ECHOCAN_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) if (test_bit(HFC_CHIP_B410P, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) vpm_echocan_on(hc, bch->slot, cq->p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) case MISDN_CTRL_HFC_ECHOCAN_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) if (test_bit(HFC_CHIP_B410P, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) vpm_echocan_off(hc, bch->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) ret = mISDN_ctrl_bchannel(bch, cq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) struct bchannel *bch = container_of(ch, struct bchannel, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) struct hfc_multi *hc = bch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) if (bch->debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) printk(KERN_DEBUG "%s: cmd:%x %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) __func__, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) case CLOSE_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) test_and_clear_bit(FLG_OPEN, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) deactivate_bchannel(bch); /* locked there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) ch->protocol = ISDN_P_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) ch->peer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) case CONTROL_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) err = channel_bctrl(bch, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) printk(KERN_WARNING "%s: unknown prim(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) * handle D-channel events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) * handle state change event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) ph_state_change(struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) struct hfc_multi *hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) int ch, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) if (!dch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) hc = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) ch = dch->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) if (dch->dev.D.protocol == ISDN_P_TE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) "%s: E1 TE (id=%d) newstate %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) __func__, hc->id, dch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) "%s: E1 NT (id=%d) newstate %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) __func__, hc->id, dch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) switch (dch->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) case (1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) if (hc->e1_state != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) for (i = 1; i <= 31; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) /* reset fifos on e1 activation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) HFC_outb_nodebug(hc, R_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) (i << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) HFC_outb_nodebug(hc, R_INC_RES_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) V_RES_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) HFC_wait_nodebug(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) test_and_set_bit(FLG_ACTIVE, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) if (hc->e1_state != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) _queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) hc->e1_state = dch->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) if (dch->dev.D.protocol == ISDN_P_TE_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) "%s: S/T TE newstate %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) __func__, dch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) switch (dch->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) case (0):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) l1_event(dch->l1, HW_RESET_IND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) case (3):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) l1_event(dch->l1, HW_DEACT_IND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) case (5):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) case (8):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) l1_event(dch->l1, ANYSIGNAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) case (6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) l1_event(dch->l1, INFO2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) case (7):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) l1_event(dch->l1, INFO4_P8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) if (debug & DEBUG_HFCMULTI_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) printk(KERN_DEBUG "%s: S/T NT newstate %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) __func__, dch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) switch (dch->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) case (2):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) if (hc->chan[ch].nt_timer == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) hc->chan[ch].nt_timer = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) HFC_outb(hc, R_ST_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) HFC_outb(hc, A_ST_WR_STATE, 4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) V_ST_LD_STA); /* G4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) udelay(6); /* wait at least 5,21us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) HFC_outb(hc, A_ST_WR_STATE, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) dch->state = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) /* one extra count for the next event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) hc->chan[ch].nt_timer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) nt_t1_count[poll_timer] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) HFC_outb(hc, R_ST_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) hc->chan[ch].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) /* allow G2 -> G3 transition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) HFC_outb(hc, A_ST_WR_STATE, 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) V_SET_G2_G3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) case (1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) hc->chan[ch].nt_timer = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) _queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) case (4):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) hc->chan[ch].nt_timer = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) case (3):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) hc->chan[ch].nt_timer = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) test_and_set_bit(FLG_ACTIVE, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) * called for card mode init message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) hfcmulti_initmode(struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) struct hfc_multi *hc = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) u_char a_st_wr_state, r_e1_wr_sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) int i, pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) printk(KERN_DEBUG "%s: entered\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) i = dch->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) pt = hc->chan[i].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) /* E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) hc->chan[hc->dnum[pt]].slot_tx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) hc->chan[hc->dnum[pt]].slot_rx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) hc->chan[hc->dnum[pt]].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) if (hc->dnum[pt]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) timer_setup(&dch->timer, hfcmulti_dbusy_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) for (i = 1; i <= 31; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) hc->chan[i].slot_tx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) hc->chan[i].slot_rx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) hc->chan[i].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) if (hc->ctype == HFC_TYPE_E1 && pt == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) /* E1, port 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) dch = hc->chan[hc->dnum[0]].dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) HFC_outb(hc, R_LOS0, 255); /* 2 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) HFC_outb(hc, R_LOS1, 255); /* 512 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) HFC_outb(hc, R_RX0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) hc->hw.r_tx0 = 0 | V_OUT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) HFC_outb(hc, R_RX0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) hc->hw.r_tx0 = 1 | V_OUT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) hc->hw.r_tx1 = V_ATX | V_NTRI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) HFC_outb(hc, R_TX0, hc->hw.r_tx0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) HFC_outb(hc, R_TX1, hc->hw.r_tx1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) HFC_outb(hc, R_TX_FR0, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) HFC_outb(hc, R_TX_FR1, 0xf8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) if (dch->dev.D.protocol == ISDN_P_NT_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) printk(KERN_DEBUG "%s: E1 port is NT-mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) r_e1_wr_sta = 0; /* G0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) hc->e1_getclock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) printk(KERN_DEBUG "%s: E1 port is TE-mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) r_e1_wr_sta = 0; /* F0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) hc->e1_getclock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) HFC_outb(hc, R_SYNC_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) hc->e1_getclock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) hc->e1_getclock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) /* SLAVE (clock master) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) "%s: E1 port is clock master "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) "(clock from PCM)\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) if (hc->e1_getclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) /* MASTER (clock slave) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) "%s: E1 port is clock slave "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) "(clock to PCM)\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) /* MASTER (clock master) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) printk(KERN_DEBUG "%s: E1 port is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) "clock master "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) "(clock from QUARTZ)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) V_PCM_SYNC | V_JATT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) HFC_outb(hc, R_SYNC_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) HFC_outb(hc, R_PWM_MD, V_PWM0_MD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) HFC_outb(hc, R_PWM0, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) HFC_outb(hc, R_PWM1, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) /* state machine setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) udelay(6); /* wait at least 5,21us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) hc->syncronized = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) plxsd_checksync(hc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) if (hc->ctype != HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) /* ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) hc->chan[i].slot_tx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) hc->chan[i].slot_rx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) hc->chan[i].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) timer_setup(&dch->timer, hfcmulti_dbusy_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) hc->chan[i - 2].slot_tx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) hc->chan[i - 2].slot_rx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) hc->chan[i - 2].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) hc->chan[i - 1].slot_tx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) hc->chan[i - 1].slot_rx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) hc->chan[i - 1].conf = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) /* select interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) HFC_outb(hc, R_ST_SEL, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) /* undocumented: delay after R_ST_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) if (dch->dev.D.protocol == ISDN_P_NT_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) "%s: ST port %d is NT-mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) __func__, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) /* clock delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) a_st_wr_state = 1; /* G1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) hc->hw.a_st_ctrl0[pt] = V_ST_MD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) "%s: ST port %d is TE-mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) __func__, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) /* clock delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) a_st_wr_state = 2; /* F2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) hc->hw.a_st_ctrl0[pt] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) hc->hw.a_st_ctrl0[pt] |= V_TX_LI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) if (hc->ctype == HFC_TYPE_XHFC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 0x7c << 1 /* V_ST_PULSE */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) /* line setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) /* disable E-channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) if ((dch->dev.D.protocol == ISDN_P_NT_S0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) HFC_outb(hc, A_ST_CTRL1, V_E_IGNO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) HFC_outb(hc, A_ST_CTRL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) /* enable B-channel receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) HFC_outb(hc, A_ST_CTRL2, V_B1_RX_EN | V_B2_RX_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) /* state machine setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) udelay(6); /* wait at least 5,21us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) hc->hw.r_sci_msk |= 1 << pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) /* state machine interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) /* unset sync on port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) hc->syncronized &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) ~(1 << hc->chan[dch->slot].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) plxsd_checksync(hc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) printk("%s: done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) struct channel_req *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) if (debug & DEBUG_HW_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) dch->dev.id, __builtin_return_address(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) if (rq->protocol == ISDN_P_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) if ((dch->dev.D.protocol != ISDN_P_NONE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) (dch->dev.D.protocol != rq->protocol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) if (debug & DEBUG_HFCMULTI_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) printk(KERN_DEBUG "%s: change protocol %x to %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) __func__, dch->dev.D.protocol, rq->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) (rq->protocol != ISDN_P_TE_S0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) l1_event(dch->l1, CLOSE_CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) if (dch->dev.D.protocol != rq->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) if (rq->protocol == ISDN_P_TE_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) err = create_l1(dch, hfcm_l1callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) dch->dev.D.protocol = rq->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) hfcmulti_initmode(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) if (test_bit(FLG_ACTIVE, &dch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 0, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) rq->ch = &dch->dev.D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) if (!try_module_get(THIS_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) printk(KERN_WARNING "%s:cannot get module\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) struct channel_req *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) int ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) if (!test_channelmap(rq->adr.channel, dch->dev.channelmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) if (rq->protocol == ISDN_P_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) if (hc->ctype == HFC_TYPE_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) ch = rq->adr.channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) ch = (rq->adr.channel - 1) + (dch->slot - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) bch = hc->chan[ch].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) if (!bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) printk(KERN_ERR "%s:internal error ch %d has no bch\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) __func__, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) return -EBUSY; /* b-channel can be only open once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) bch->ch.protocol = rq->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) hc->chan[ch].rx_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) rq->ch = &bch->ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) if (!try_module_get(THIS_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) printk(KERN_WARNING "%s:cannot get module\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) * device control function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) struct hfc_multi *hc = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) int wd_mode, wd_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) switch (cq->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) case MISDN_CTRL_GETOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_L1_TIMER3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) wd_cnt = cq->p1 & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) wd_mode = !!(cq->p1 >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) ", counter 0x%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) wd_mode ? "AUTO" : "MANUAL", wd_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) /* set the watchdog timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) if (hc->ctype == HFC_TYPE_XHFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) /* init the watchdog register and reset the counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) /* enable the watchdog output for Speech-Design */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) HFC_outb(hc, R_GPIO_OUT1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) if (debug & DEBUG_HFCMULTI_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) case MISDN_CTRL_L1_TIMER3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) ret = l1_event(dch->l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) printk(KERN_WARNING "%s: unknown Op %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) __func__, cq->op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) struct dchannel *dch = container_of(dev, struct dchannel, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) struct hfc_multi *hc = dch->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) struct channel_req *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) if (dch->debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) printk(KERN_DEBUG "%s: cmd:%x %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) __func__, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) case OPEN_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) rq = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) switch (rq->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) case ISDN_P_TE_S0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) case ISDN_P_NT_S0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) err = open_dchannel(hc, dch, rq); /* locked there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) case ISDN_P_TE_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) case ISDN_P_NT_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) if (hc->ctype != HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) err = open_dchannel(hc, dch, rq); /* locked there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) err = open_bchannel(hc, dch, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) case CLOSE_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) if (debug & DEBUG_HW_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) __func__, dch->dev.id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) __builtin_return_address(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) case CONTROL_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) err = channel_dctrl(dch, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) if (dch->debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) printk(KERN_DEBUG "%s: unknown command %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) clockctl(void *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) struct hfc_multi *hc = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) hc->iclock_on = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) * initialize the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) * start timer irq, wait some time and check if we have interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) * if not, reset chip and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) init_card(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) int err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) void __iomem *plx_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) u_long plx_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) printk(KERN_DEBUG "%s: entered\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) /* set interrupts but leave global interrupt disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) hc->hw.r_irq_ctrl = V_FIFO_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) disable_hwirq(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) "HFC-multi", hc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) hc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) hc->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) plx_acc = hc->plx_membase + PLX_INTCSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) plx_acc); /* enable PCI & LINT1 irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) printk(KERN_DEBUG "%s: IRQ %d count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) __func__, hc->irq, hc->irqcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) err = init_chip(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) * Finally enable IRQ output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) * this is only allowed, if an IRQ routine is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) * established for this HFC, so don't do that earlier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) enable_hwirq(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) /* printk(KERN_DEBUG "no master irq set!!!\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) set_current_state(TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) schedule_timeout((100 * HZ) / 1000); /* Timeout 100ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) /* turn IRQ off until chip is completely initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) disable_hwirq(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) printk(KERN_DEBUG "%s: IRQ %d count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) __func__, hc->irq, hc->irqcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) if (hc->irqcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) printk(KERN_DEBUG "%s: done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) printk(KERN_INFO "ignoring missing interrupts\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) hc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) spin_lock_irqsave(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) plx_acc = hc->plx_membase + PLX_INTCSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) writew(0x00, plx_acc); /*disable IRQs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) spin_unlock_irqrestore(&plx_lock, plx_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) if (hc->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) free_irq(hc->irq, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) hc->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) * find pci device and set it up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) struct hm_map *m = (struct hm_map *)ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) hc->pci_dev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) if (m->clock2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) if (ent->vendor == PCI_VENDOR_ID_DIGIUM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) ent->device == PCI_DEVICE_ID_DIGIUM_HFC4S) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) test_and_set_bit(HFC_CHIP_B410P, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) hc->slots = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) if (hc->pci_dev->irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) if (pci_enable_device(hc->pci_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) hc->leds = m->leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) hc->ledstate = 0xAFFEAFFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) hc->opticalsupport = m->opticalsupport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) hc->pci_iobase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) hc->pci_membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) hc->plx_membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) /* set memory access methods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) if (m->io_mode) /* use mode from card config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) hc->io_mode = m->io_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) switch (hc->io_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) case HFC_IO_MODE_PLXSD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) hc->slots = 128; /* required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) hc->HFC_outb = HFC_outb_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) hc->HFC_inb = HFC_inb_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) hc->HFC_inw = HFC_inw_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) hc->HFC_wait = HFC_wait_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) hc->read_fifo = read_fifo_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) hc->write_fifo = write_fifo_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) hc->plx_origmembase = hc->pci_dev->resource[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) /* MEMBASE 1 is PLX PCI Bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) if (!hc->plx_origmembase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) hc->plx_membase = ioremap(hc->plx_origmembase, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) if (!hc->plx_membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) "HFC-multi: failed to remap plx address space. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) "(internal error)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) (u_long)hc->plx_membase, hc->plx_origmembase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) hc->pci_origmembase = hc->pci_dev->resource[2].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) /* MEMBASE 1 is PLX PCI Bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) if (!hc->pci_origmembase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) "HFC-multi: No IO-Memory for PCI card found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) hc->pci_membase = ioremap(hc->pci_origmembase, 0x400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) if (!hc->pci_membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) printk(KERN_WARNING "HFC-multi: failed to remap io "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) "address space. (internal error)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) "leds-type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) hc->pci_dev->irq, HZ, hc->leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) case HFC_IO_MODE_PCIMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) hc->HFC_outb = HFC_outb_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) hc->HFC_inb = HFC_inb_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) hc->HFC_inw = HFC_inw_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) hc->HFC_wait = HFC_wait_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) hc->read_fifo = read_fifo_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) hc->write_fifo = write_fifo_pcimem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) hc->pci_origmembase = hc->pci_dev->resource[1].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) if (!hc->pci_origmembase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) "HFC-multi: No IO-Memory for PCI card found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) hc->pci_membase = ioremap(hc->pci_origmembase, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) if (!hc->pci_membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) "HFC-multi: failed to remap io address space. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) "(internal error)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) case HFC_IO_MODE_REGIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) hc->HFC_outb = HFC_outb_regio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) hc->HFC_inb = HFC_inb_regio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) hc->HFC_inw = HFC_inw_regio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) hc->HFC_wait = HFC_wait_regio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) hc->read_fifo = read_fifo_regio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) hc->write_fifo = write_fifo_regio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) if (!hc->pci_iobase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) "HFC-multi: No IO for PCI card found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) if (!request_region(hc->pci_iobase, 8, "hfcmulti")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) printk(KERN_WARNING "HFC-multi: failed to request "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) "address space at 0x%08lx (internal error)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) hc->pci_dev->irq, HZ, hc->leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) pci_disable_device(hc->pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) pci_set_drvdata(hc->pci_dev, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) /* At this point the needed PCI config is done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) /* fifos are still not enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) * remove port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) release_port(struct hfc_multi *hc, struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) int pt, ci, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) struct bchannel *pb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) ci = dch->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) pt = hc->chan[ci].port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) printk(KERN_DEBUG "%s: entered for port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) __func__, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) if (pt >= hc->ports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) printk(KERN_WARNING "%s: ERROR port out of range (%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) __func__, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) printk(KERN_DEBUG "%s: releasing port=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) __func__, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) if (dch->dev.D.protocol == ISDN_P_TE_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) l1_event(dch->l1, CLOSE_CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) hc->chan[ci].dch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) if (hc->created[pt]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) hc->created[pt] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) mISDN_unregister_device(&dch->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) if (dch->timer.function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) del_timer(&dch->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) dch->timer.function = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) if (hc->ctype == HFC_TYPE_E1) { /* E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) /* remove sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) hc->syncronized = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) plxsd_checksync(hc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) /* free channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) for (i = 0; i <= 31; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) if (hc->chan[i].bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) "%s: free port %d channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) __func__, hc->chan[i].port + 1, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) pb = hc->chan[i].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) hc->chan[i].bch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) mISDN_freebchannel(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) kfree(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) kfree(hc->chan[i].coeff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) /* remove sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) hc->syncronized &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) ~(1 << hc->chan[ci].port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) plxsd_checksync(hc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) /* free channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) if (hc->chan[ci - 2].bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) "%s: free port %d channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) __func__, hc->chan[ci - 2].port + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) ci - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) pb = hc->chan[ci - 2].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) hc->chan[ci - 2].bch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) mISDN_freebchannel(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) kfree(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) kfree(hc->chan[ci - 2].coeff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) if (hc->chan[ci - 1].bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) "%s: free port %d channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) __func__, hc->chan[ci - 1].port + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) ci - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) pb = hc->chan[ci - 1].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) hc->chan[ci - 1].bch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) mISDN_freebchannel(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) kfree(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) kfree(hc->chan[ci - 1].coeff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) pt+1, ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) mISDN_freedchannel(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) kfree(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) printk(KERN_DEBUG "%s: done!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) release_card(struct hfc_multi *hc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) int ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) printk(KERN_DEBUG "%s: release card (%d) entered\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) __func__, hc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) /* unregister clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) if (hc->iclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) mISDN_unregister_clock(hc->iclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) /* disable and free irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) disable_hwirq(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) if (hc->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) __func__, hc->irq, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) free_irq(hc->irq, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) hc->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) /* disable D-channels & B-channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) printk(KERN_DEBUG "%s: disable all channels (d and b)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) for (ch = 0; ch <= 31; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) if (hc->chan[ch].dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) release_port(hc, hc->chan[ch].dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) /* dimm leds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) if (hc->leds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) hfcmulti_leds(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) /* release hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) release_io_hfcmulti(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) printk(KERN_DEBUG "%s: remove instance from list\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) list_del(&hc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) printk(KERN_DEBUG "%s: delete instance\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) if (hc == syncmaster)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) syncmaster = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) kfree(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) printk(KERN_DEBUG "%s: card successfully removed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) /* set optical line type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) if (port[Port_cnt] & 0x001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) if (!m->opticalsupport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) "This board has no optical "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) "support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) "%s: PORT set optical "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) "interfacs: card(%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) "port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) test_and_set_bit(HFC_CFG_OPTICAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) &hc->chan[hc->dnum[0]].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) /* set LOS report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) if (port[Port_cnt] & 0x004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) printk(KERN_DEBUG "%s: PORT set "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) "LOS report: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) test_and_set_bit(HFC_CFG_REPORT_LOS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) &hc->chan[hc->dnum[0]].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) /* set AIS report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) if (port[Port_cnt] & 0x008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) printk(KERN_DEBUG "%s: PORT set "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) "AIS report: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) test_and_set_bit(HFC_CFG_REPORT_AIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) &hc->chan[hc->dnum[0]].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) /* set SLIP report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) if (port[Port_cnt] & 0x010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) "%s: PORT set SLIP report: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) "card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) test_and_set_bit(HFC_CFG_REPORT_SLIP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) &hc->chan[hc->dnum[0]].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) /* set RDI report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) if (port[Port_cnt] & 0x020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) "%s: PORT set RDI report: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) "card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) test_and_set_bit(HFC_CFG_REPORT_RDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) &hc->chan[hc->dnum[0]].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) /* set CRC-4 Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) if (!(port[Port_cnt] & 0x100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) printk(KERN_DEBUG "%s: PORT turn on CRC4 report:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) " card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) test_and_set_bit(HFC_CFG_CRC4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) &hc->chan[hc->dnum[0]].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) printk(KERN_DEBUG "%s: PORT turn off CRC4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) " report: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) /* set forced clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) if (port[Port_cnt] & 0x0200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) printk(KERN_DEBUG "%s: PORT force getting clock from "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) "E1: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) if (port[Port_cnt] & 0x0400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) printk(KERN_DEBUG "%s: PORT force putting clock to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) "E1: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) /* set JATT PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) if (port[Port_cnt] & 0x0800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) printk(KERN_DEBUG "%s: PORT disable JATT PLL on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) "E1: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) __func__, HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) /* set elastic jitter buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) if (port[Port_cnt] & 0x3000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) "%s: PORT set elastic "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) "buffer to %d: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) __func__, hc->chan[hc->dnum[0]].jitter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) HFC_cnt + 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) hc->chan[hc->dnum[0]].jitter = 2; /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) int ch, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) char name[MISDN_MAX_IDLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) int bcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) if (!dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) dch->debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) dch->hw = hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) dch->dev.D.send = handle_dmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) dch->dev.D.ctrl = hfcm_dctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) dch->slot = hc->dnum[pt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) hc->chan[hc->dnum[pt]].dch = dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) hc->chan[hc->dnum[pt]].port = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) hc->chan[hc->dnum[pt]].nt_timer = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) for (ch = 1; ch <= 31; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) if (!bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) printk(KERN_ERR "%s: no memory for bchannel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) if (!hc->chan[ch].coeff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) printk(KERN_ERR "%s: no memory for coeffs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) kfree(bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) bch->nr = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) bch->slot = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) bch->debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) bch->hw = hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) bch->ch.send = handle_bmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) bch->ch.ctrl = hfcm_bctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) bch->ch.nr = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) list_add(&bch->ch.list, &dch->dev.bchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) hc->chan[ch].bch = bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) hc->chan[ch].port = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) set_channelmap(bch->nr, dch->dev.channelmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) bcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) dch->dev.nrbchan = bcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) if (pt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) init_e1_port_hw(hc, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) if (hc->ports > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) HFC_cnt + 1, pt+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) hc->created[pt] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) free_chan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) release_port(hc, dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) init_multi_port(struct hfc_multi *hc, int pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) struct dchannel *dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) int ch, i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) char name[MISDN_MAX_IDLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) if (!dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) dch->debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) dch->hw = hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) dch->dev.D.send = handle_dmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) dch->dev.D.ctrl = hfcm_dctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) dch->dev.nrbchan = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) i = pt << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) dch->slot = i + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) hc->chan[i + 2].dch = dch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) hc->chan[i + 2].port = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) hc->chan[i + 2].nt_timer = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) for (ch = 0; ch < dch->dev.nrbchan; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) if (!bch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) printk(KERN_ERR "%s: no memory for bchannel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) if (!hc->chan[i + ch].coeff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) printk(KERN_ERR "%s: no memory for coeffs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) kfree(bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) bch->nr = ch + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) bch->slot = i + ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) bch->debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) bch->hw = hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) bch->ch.send = handle_bmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) bch->ch.ctrl = hfcm_bctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) bch->ch.nr = ch + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) list_add(&bch->ch.list, &dch->dev.bchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) hc->chan[i + ch].bch = bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) hc->chan[i + ch].port = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) set_channelmap(bch->nr, dch->dev.channelmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) /* set master clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) if (port[Port_cnt] & 0x001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) "%s: PROTOCOL set master clock: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) "card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) __func__, HFC_cnt + 1, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) if (dch->dev.D.protocol != ISDN_P_TE_S0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) printk(KERN_ERR "Error: Master clock "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) "for port(%d) of card(%d) is only"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) " possible with TE-mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) pt + 1, HFC_cnt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) if (hc->masterclk >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) printk(KERN_ERR "Error: Master clock "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) "for port(%d) of card(%d) already "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) "defined for port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) pt + 1, HFC_cnt + 1, hc->masterclk + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) hc->masterclk = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) /* set transmitter line to non capacitive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) if (port[Port_cnt] & 0x002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) "%s: PROTOCOL set non capacitive "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) "transmitter: card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) __func__, HFC_cnt + 1, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) test_and_set_bit(HFC_CFG_NONCAP_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) &hc->chan[i + 2].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) /* disable E-channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) if (port[Port_cnt] & 0x004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) "%s: PROTOCOL disable E-channel: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) "card(%d) port(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) __func__, HFC_cnt + 1, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) test_and_set_bit(HFC_CFG_DIS_ECHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) &hc->chan[i + 2].cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) if (hc->ctype == HFC_TYPE_XHFC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) HFC_cnt + 1, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) ret = mISDN_register_device(&dch->dev, NULL, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) hc->ctype, HFC_cnt + 1, pt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) goto free_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) hc->created[pt] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) free_chan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) release_port(hc, dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) int ret_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) int pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) struct hfc_multi *hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) int i, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) u_int maskcheck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) if (HFC_cnt >= MAX_CARDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) printk(KERN_ERR "too many cards (max=%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) MAX_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) "type[%d] %d was supplied as module parameter\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) m->vendor_name, m->card_name, m->type, HFC_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) type[HFC_cnt] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) printk(KERN_WARNING "HFC-MULTI: Load module without parameters "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) "first, to see cards and their types.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) __func__, m->vendor_name, m->card_name, m->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) type[HFC_cnt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) /* allocate card+fifo structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) if (!hc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) printk(KERN_ERR "No kmem for HFC-Multi card\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) spin_lock_init(&hc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) hc->mtyp = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) hc->ctype = m->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) hc->ports = m->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) hc->id = HFC_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) hc->pcm = pcm[HFC_cnt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) hc->io_mode = iomode[HFC_cnt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) /* fragment card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) pt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) maskcheck = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) for (ch = 0; ch <= 31; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) if (!((1 << ch) & dmask[E1_cnt]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) hc->dnum[pt] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) hc->bmask[pt] = bmask[bmask_cnt++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) if ((maskcheck & hc->bmask[pt])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) || (dmask[E1_cnt] & hc->bmask[pt])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) E1_cnt + 1, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) kfree(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) maskcheck |= hc->bmask[pt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) E1_cnt + 1, ch, hc->bmask[pt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) pt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) hc->ports = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) /* default card layout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) hc->dnum[0] = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) hc->bmask[0] = 0xfffefffe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) hc->ports = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) /* set chip specific features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) hc->masterclk = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) if (type[HFC_cnt] & 0x100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) hc->silence = 0xff; /* ulaw silence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) hc->silence = 0x2a; /* alaw silence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) if ((poll >> 1) > sizeof(hc->silence_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) printk(KERN_ERR "HFCMULTI error: silence_data too small, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) "please fix\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) kfree(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) for (i = 0; i < (poll >> 1); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) hc->silence_data[i] = hc->silence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) if (hc->ctype != HFC_TYPE_XHFC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) if (!(type[HFC_cnt] & 0x200))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) test_and_set_bit(HFC_CHIP_CONF, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) if (type[HFC_cnt] & 0x800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) if (type[HFC_cnt] & 0x1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) if (type[HFC_cnt] & 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) if (type[HFC_cnt] & 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) hc->slots = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) if (type[HFC_cnt] & 0x10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) hc->slots = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) if (type[HFC_cnt] & 0x20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) hc->slots = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) if (type[HFC_cnt] & 0x80000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) hc->wdcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) hc->wdbyte = V_GPIO_OUT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) printk(KERN_NOTICE "Watchdog enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) if (pdev && ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) /* setup pci, hc->slots may change due to PLXSD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) ret_err = setup_pci(hc, pdev, ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) #ifdef CONFIG_MISDN_HFCMULTI_8xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) ret_err = setup_embedded(hc, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) printk(KERN_WARNING "Embedded IO Mode not selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) ret_err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) if (ret_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) if (hc == syncmaster)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) syncmaster = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) kfree(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) return ret_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) hc->HFC_outb_nodebug = hc->HFC_outb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) hc->HFC_inb_nodebug = hc->HFC_inb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) hc->HFC_inw_nodebug = hc->HFC_inw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) hc->HFC_wait_nodebug = hc->HFC_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) #ifdef HFC_REGISTER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) hc->HFC_outb = HFC_outb_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) hc->HFC_inb = HFC_inb_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) hc->HFC_inw = HFC_inw_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) hc->HFC_wait = HFC_wait_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) /* create channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) for (pt = 0; pt < hc->ports; pt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) if (Port_cnt >= MAX_PORTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) printk(KERN_ERR "too many ports (max=%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) MAX_PORTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) ret_err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) if (hc->ctype == HFC_TYPE_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) ret_err = init_e1_port(hc, m, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) ret_err = init_multi_port(hc, pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) "%s: Registering D-channel, card(%d) port(%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) "result %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) __func__, HFC_cnt + 1, pt + 1, ret_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) if (ret_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) while (pt) { /* release already registered ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) pt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) if (hc->ctype == HFC_TYPE_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) release_port(hc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) hc->chan[hc->dnum[pt]].dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) release_port(hc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) hc->chan[(pt << 2) + 2].dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) if (hc->ctype != HFC_TYPE_E1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) Port_cnt++; /* for each S0 port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) if (hc->ctype == HFC_TYPE_E1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) Port_cnt++; /* for each E1 port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) E1_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) /* disp switches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) switch (m->dip_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) case DIP_4S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) * Get DIP setting for beroNet 1S/2S/4S cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) * DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) * GPI 19/23 (R_GPI_IN2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) ((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) (~HFC_inb(hc, R_GPI_IN2) & 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) /* Port mode (TE/NT) jumpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4) & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) if (test_bit(HFC_CHIP_B410P, &hc->chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) pmj = ~pmj & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) m->vendor_name, m->card_name, dips, pmj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) case DIP_8S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) * Get DIP Setting for beroNet 8S0+ cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) * Enable PCI auxbridge function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) /* prepare access to auxport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) outw(0x4000, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) * some dummy reads are required to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) * read valid DIP switch data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) dips = inb(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) dips = inb(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) dips = inb(hc->pci_iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) dips = ~inb(hc->pci_iobase) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) outw(0x0, hc->pci_iobase + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) /* disable PCI auxbridge function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) m->vendor_name, m->card_name, dips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) case DIP_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) * get DIP Setting for beroNet E1 cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) m->vendor_name, m->card_name, dips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) /* add to list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) spin_lock_irqsave(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) list_add_tail(&hc->list, &HFClist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) spin_unlock_irqrestore(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) /* use as clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) if (clock == HFC_cnt + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) /* initialize hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) hc->irq = (m->irq) ? : hc->pci_dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) ret_err = init_card(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) if (ret_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) printk(KERN_ERR "init card returns %d\n", ret_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) release_card(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) return ret_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) /* start IRQ and return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) spin_lock_irqsave(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) enable_hwirq(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) spin_unlock_irqrestore(&hc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) free_card:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) release_io_hfcmulti(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) if (hc == syncmaster)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) syncmaster = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) kfree(hc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) return ret_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) static void hfc_remove_pci(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) struct hfc_multi *card = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) printk(KERN_INFO "removing hfc_multi card vendor:%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) "device:%x subvendor:%x subdevice:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) pdev->vendor, pdev->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) pdev->subsystem_vendor, pdev->subsystem_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) if (card) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) spin_lock_irqsave(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) release_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) spin_unlock_irqrestore(&HFClock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) printk(KERN_DEBUG "%s: drvdata already removed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) #define VENDOR_CCD "Cologne Chip AG"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) #define VENDOR_BN "beroNet GmbH"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) #define VENDOR_DIG "Digium Inc."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) #define VENDOR_JH "Junghanns.NET GmbH"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) #define VENDOR_PRIM "PrimuX"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) static const struct hm_map hfcm_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) HFC_IO_MODE_REGIO, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) HFC_IO_MODE_PLXSD, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) HFC_IO_MODE_PLXSD, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) HFC_IO_MODE_EMBSD, XHFC_IRQ},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) /*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) /*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) #undef H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) #define H(x) ((unsigned long)&hfcm_map[x])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) static const struct pci_device_id hfmultipci_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) /* Cards with HFC-4S Chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) { PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) 0xb761, 0, 0, H(33)}, /* BN2S PCIe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) 0xb762, 0, 0, H(34)}, /* BN4S PCIe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) /* Cards with HFC-8S Chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) /* Cards with HFC-E1 Chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFCE1), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) {0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) #undef H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) MODULE_DEVICE_TABLE(pci, hfmultipci_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) struct hm_map *m = (struct hm_map *)ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) "Unknown HFC multiport controller (vendor:%04x device:%04x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) pdev->device, pdev->subsystem_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) pdev->subsystem_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) "Please contact the driver maintainer for support.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) ret = hfcmulti_init(m, pdev, ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) HFC_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) printk(KERN_INFO "%d devices registered\n", HFC_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) static struct pci_driver hfcmultipci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) .name = "hfc_multi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) .probe = hfcmulti_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) .remove = hfc_remove_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) .id_table = hfmultipci_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) static void __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) HFCmulti_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) struct hfc_multi *card, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) /* get rid of all devices of this driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) list_for_each_entry_safe(card, next, &HFClist, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) release_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) pci_unregister_driver(&hfcmultipci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) HFCmulti_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) int i, xhfc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) struct hm_map m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) #ifdef IRQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) printk(KERN_DEBUG "%s: IRQ_DEBUG IS ENABLED!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) spin_lock_init(&HFClock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) spin_lock_init(&plx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) if (debug & DEBUG_HFCMULTI_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) printk(KERN_DEBUG "%s: init entered\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) switch (poll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) poll_timer = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) poll = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) poll_timer = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) poll_timer = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) poll_timer = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) case 64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) poll_timer = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) case 128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) poll_timer = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) case 256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) poll_timer = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) "%s: Wrong poll value (%d).\n", __func__, poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) if (!clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) clock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) /* Register the embedded devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) * This should be done before the PCI cards registration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) switch (hwid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) case HWID_MINIP4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) xhfc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) m = hfcm_map[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) case HWID_MINIP8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) xhfc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) m = hfcm_map[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) case HWID_MINIP16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) xhfc = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) m = hfcm_map[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) xhfc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) for (i = 0; i < xhfc; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) err = hfcmulti_init(&m, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) printk(KERN_ERR "error registering embedded driver: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) "%x\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) HFC_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) printk(KERN_INFO "%d devices registered\n", HFC_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) /* Register the PCI cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) err = pci_register_driver(&hfcmultipci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) printk(KERN_ERR "error registering pci driver: %x\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) module_init(HFCmulti_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) module_exit(HFCmulti_cleanup);