^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mISDNisar.c ISAR (Siemens PSB 7110) specific functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author Karsten Keil (keil@isdn4linux.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* define this to enable static debug messages, if you kernel supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * dynamic debugging, you should use debugfs for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* #define DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mISDNhw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "isar.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define ISAR_REV "2.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_AUTHOR("Karsten Keil");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MODULE_VERSION(ISAR_REV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DEBUG_HW_FIRMWARE_FIFO 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 122, 145, 146};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define FAXMODCNT 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void isar_setup(struct isar_hw *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) waitforHIA(struct isar_hw *isar, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int t = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 val = isar->read_reg(isar->hw, ISAR_HIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) while ((val & 1) && t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) t--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) val = isar->read_reg(isar->hw, ISAR_HIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pr_debug("%s: HIA after %dus\n", isar->name, timeout - t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * send msg to ISAR mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * if msg is NULL use isar->buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (!waitforHIA(isar, 1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) pr_debug("send_mbox(%02x,%02x,%d)\n", his, creg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) isar->write_reg(isar->hw, ISAR_CTRL_H, creg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) isar->write_reg(isar->hw, ISAR_CTRL_L, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) isar->write_reg(isar->hw, ISAR_WADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) msg = isar->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (msg && len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) isar->write_fifo(isar->hw, ISAR_MBOX, msg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) while (l < (int)len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) hex_dump_to_buffer(msg + l, len - l, 32, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) isar->log, 256, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) pr_debug("%s: %s %02x: %s\n", isar->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) __func__, l, isar->log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) l += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) isar->write_reg(isar->hw, ISAR_HIS, his);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) waitforHIA(isar, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * receive message from ISAR mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * if msg is NULL use isar->buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rcv_mbox(struct isar_hw *isar, u8 *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) msg = isar->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) isar->write_reg(isar->hw, ISAR_RADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (msg && isar->clsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) isar->read_fifo(isar->hw, ISAR_MBOX, msg, isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) while (l < (int)isar->clsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 1, isar->log, 256, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) pr_debug("%s: %s %02x: %s\n", isar->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __func__, l, isar->log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) l += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) isar->write_reg(isar->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) get_irq_infos(struct isar_hw *isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) isar->iis = isar->read_reg(isar->hw, ISAR_IIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) isar->iis, isar->cmsb, isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * poll answer message from ISAR mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * should be used only with ISAR IRQs disabled before DSP was started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) poll_mbox(struct isar_hw *isar, int maxdelay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int t = maxdelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) irq = isar->read_reg(isar->hw, ISAR_IRQBIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) while (t && !(irq & ISAR_IRQSTA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) t--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) get_irq_infos(isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) rcv_mbox(isar, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) pr_debug("%s: pulled %d bytes after %d us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) isar->name, isar->clsb, maxdelay - t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return t;
^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) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ISARVersion(struct isar_hw *isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* disable ISAR IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) isar->buf[0] = ISAR_MSG_HWVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) isar->buf[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) isar->buf[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!send_mbox(isar, ISAR_HIS_VNR, 0, 3, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!poll_mbox(isar, 1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (isar->iis == ISAR_IIS_VNR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (isar->clsb == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ver = isar->buf[0] & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) load_firmware(struct isar_hw *isar, const u8 *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 saved_debug = isar->ch[0].bch.debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int ret, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 nom, noc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u16 left, val, *sp = (u16 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u16 sadr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u16 d_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) } blk_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (1 != isar->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pr_err("%s: ISAR wrong version %d firmware download aborted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) isar->name, isar->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) pr_debug("%s: load firmware %d words (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) isar->name, size / 2, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) size /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* disable ISAR IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) while (cnt < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) blk_head.sadr = le16_to_cpu(*sp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) blk_head.len = le16_to_cpu(*sp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) blk_head.d_key = le16_to_cpu(*sp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) cnt += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) pr_debug("ISAR firmware block (%#x,%d,%#x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) left = blk_head.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (cnt + left > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) pr_info("%s: firmware error have %d need %d words\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) isar->name, size, cnt + left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 0, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pr_info("ISAR send_mbox dkey failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!poll_mbox(isar, 1000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) pr_warn("ISAR poll_mbox dkey failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if ((isar->iis != ISAR_IIS_DKEY) || isar->cmsb || isar->clsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pr_info("ISAR wrong dkey response (%x,%x,%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) isar->iis, isar->cmsb, isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) while (left > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (left > 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) noc = 126;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) noc = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) nom = (2 * noc) + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mp = isar->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* the ISAR is big endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *mp++ = blk_head.sadr >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *mp++ = blk_head.sadr & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) left -= noc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) cnt += noc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *mp++ = noc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) pr_debug("%s: load %3d words at %04x\n", isar->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) noc, blk_head.sadr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) blk_head.sadr += noc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) while (noc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) val = le16_to_cpu(*sp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *mp++ = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *mp++ = val & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) noc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!send_mbox(isar, ISAR_HIS_FIRM, 0, nom, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pr_info("ISAR send_mbox prog failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (!poll_mbox(isar, 1000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pr_info("ISAR poll_mbox prog failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if ((isar->iis != ISAR_IIS_FIRM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) isar->cmsb || isar->clsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pr_info("ISAR wrong prog response (%x,%x,%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) isar->iis, isar->cmsb, isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) pr_debug("%s: ISAR firmware block %d words loaded\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) isar->name, blk_head.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) isar->ch[0].bch.debug = saved_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* 10ms delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cnt = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) isar->buf[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) isar->buf[1] = 0xfe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) isar->bstat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!send_mbox(isar, ISAR_HIS_STDSP, 0, 2, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pr_info("ISAR send_mbox start dsp failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!poll_mbox(isar, 1000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pr_info("ISAR poll_mbox start dsp failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if ((isar->iis != ISAR_IIS_STDSP) || isar->cmsb || isar->clsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pr_info("ISAR wrong start dsp response (%x,%x,%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) isar->iis, isar->cmsb, isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pr_debug("%s: ISAR start dsp success\n", isar->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* NORMAL mode entered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Enable IRQs of ISAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) isar->write_reg(isar->hw, ISAR_IRQBIT, ISAR_IRQSTA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) cnt = 1000; /* max 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) while ((!isar->bstat) && cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pr_info("ISAR no general status event received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pr_debug("%s: ISAR general status event %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) isar->name, isar->bstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* 10ms delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cnt = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) isar->iis = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) pr_info("ISAR send_mbox self tst failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) cnt = 10000; /* max 100 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) pr_info("ISAR no self tst response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if ((isar->cmsb == ISAR_CTRL_STST) && (isar->clsb == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) && (isar->buf[0] == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pr_debug("%s: ISAR selftest OK\n", isar->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pr_info("ISAR selftest not OK %x/%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) isar->cmsb, isar->clsb, isar->buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) isar->iis = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) pr_info("ISAR RQST SVN failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto reterror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) cnt = 30000; /* max 300 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pr_info("ISAR no SVN response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) pr_notice("%s: ISAR software version %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) isar->name, isar->buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) pr_info("%s: ISAR wrong swver response (%x,%x)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) " cnt(%d)\n", isar->name, isar->cmsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) isar->clsb, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto reterrflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) isar_setup(isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) reterrflg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) spin_lock_irqsave(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) reterror:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) isar->ch[0].bch.debug = saved_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* disable ISAR IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) spin_unlock_irqrestore(isar->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) deliver_status(struct isar_ch *ch, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) pr_debug("%s: HL->LL FAXIND %x\n", ch->is->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) _queue_data(&ch->bch.ch, PH_CONTROL_IND, status, 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) isar_rcv_frame(struct isar_ch *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) u8 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!ch->is->clsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) pr_debug("%s; ISAR zero len frame\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (test_bit(FLG_RX_OFF, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ch->bch.dropcnt += ch->is->clsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) switch (ch->bch.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case ISDN_P_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) case ISDN_P_B_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) case ISDN_P_B_L2DTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case ISDN_P_B_MODEM_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (maxlen < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) pr_warn("%s.B%d: No bufferspace for %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ch->is->name, ch->bch.nr, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) recv_Bchannel(&ch->bch, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case ISDN_P_B_HDLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (maxlen < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pr_warn("%s.B%d: No bufferspace for %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ch->is->name, ch->bch.nr, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (ch->is->cmsb & HDLC_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) pr_debug("%s: ISAR frame error %x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ch->is->name, ch->is->cmsb, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #ifdef ERROR_STATISTIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (ch->is->cmsb & HDLC_ERR_RER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ch->bch.err_inv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (ch->is->cmsb & HDLC_ERR_CER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ch->bch.err_crc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (ch->is->cmsb & HDLC_FSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) rcv_mbox(ch->is, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (ch->is->cmsb & HDLC_FED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pr_debug("%s: ISAR frame to short %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ch->is->name, ch->bch.rx_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) recv_Bchannel(&ch->bch, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case ISDN_P_B_T30_FAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (ch->state != STFAX_ACTIV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) pr_debug("%s: isar_rcv_frame: not ACTIV\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ch->bch.rx_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!ch->bch.rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (unlikely(!ch->bch.rx_skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pr_info("%s: B receive out of memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (ch->cmd == PCTRL_CMD_FRM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) pr_debug("%s: isar_rcv_frame: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ch->is->name, ch->bch.rx_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ch->is->cmsb & SART_NMD) { /* ABORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) pr_debug("%s: isar_rcv_frame: no more data\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) send_mbox(ch->is, SET_DPS(ch->dpath) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* set_skb_flag(skb, DF_NOMOREDATA); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) recv_Bchannel(&ch->bch, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (ch->is->cmsb & SART_NMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) deliver_status(ch, HW_MOD_NOCARR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (ch->cmd != PCTRL_CMD_FRH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ch->is->name, ch->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (ch->bch.rx_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* PCTRL_CMD_FRH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if ((ch->bch.rx_skb->len + ch->is->clsb) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) (ch->bch.maxlen + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) pr_info("%s: %s incoming packet too large\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ch->is->name, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) } else if (ch->is->cmsb & HDLC_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pr_info("%s: ISAR frame error %x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ch->is->name, ch->is->cmsb, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (ch->is->cmsb & HDLC_FSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rcv_mbox(ch->is, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (ch->is->cmsb & HDLC_FED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pr_info("%s: ISAR frame to short %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ch->is->name, ch->bch.rx_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) recv_Bchannel(&ch->bch, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (ch->is->cmsb & SART_NMD) { /* ABORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) pr_debug("%s: isar_rcv_frame: no more data\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (ch->bch.rx_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) skb_trim(ch->bch.rx_skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) send_mbox(ch->is, SET_DPS(ch->dpath) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) deliver_status(ch, HW_MOD_NOCARR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) pr_info("isar_rcv_frame protocol (%x)error\n", ch->bch.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) isar_fill_fifo(struct isar_ch *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u8 msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) u8 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pr_debug("%s: ch%d tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!(ch->is->bstat &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (!ch->bch.tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) (ch->bch.state != ISDN_P_B_RAW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) count = ch->mml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* use the card buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) memset(ch->is->buf, ch->bch.fill[0], count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 0, count, ch->is->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) count = ch->bch.tx_skb->len - ch->bch.tx_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (count <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (count > ch->mml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) msb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) count = ch->mml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) msb = HDLC_FED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ptr = ch->bch.tx_skb->data + ch->bch.tx_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!ch->bch.tx_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) pr_debug("%s: frame start\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if ((ch->bch.state == ISDN_P_B_T30_FAX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) (ch->cmd == PCTRL_CMD_FTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* last frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) test_and_set_bit(FLG_LASTDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) pr_debug("%s: set LASTDATA\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (msb == HDLC_FED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) test_and_set_bit(FLG_DLEETX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) msb |= HDLC_FST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ch->bch.tx_idx += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) switch (ch->bch.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) case ISDN_P_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pr_info("%s: wrong protocol 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) case ISDN_P_B_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) case ISDN_P_B_L2DTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case ISDN_P_B_MODEM_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 0, count, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case ISDN_P_B_HDLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) msb, count, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case ISDN_P_B_T30_FAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (ch->state != STFAX_ACTIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) pr_debug("%s: not ACTIV\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) else if (ch->cmd == PCTRL_CMD_FTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) msb, count, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) else if (ch->cmd == PCTRL_CMD_FTM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 0, count, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pr_debug("%s: not FTH/FTM\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pr_info("%s: protocol(%x) error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) __func__, ch->bch.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static inline struct isar_ch *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) sel_bch_isar(struct isar_hw *isar, u8 dpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct isar_ch *base = &isar->ch[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if ((!dpath) || (dpath > 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (base->dpath == dpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) base++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (base->dpath == dpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) send_next(struct isar_ch *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ch->bch.tx_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (ch->bch.state == ISDN_P_B_T30_FAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ch->cmd == PCTRL_CMD_FTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) pr_debug("set NMD_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) } else if (ch->cmd == PCTRL_CMD_FTM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (test_bit(FLG_DLEETX, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) dev_kfree_skb(ch->bch.tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (get_next_bframe(&ch->bch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) isar_fill_fifo(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) } else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) isar_fill_fifo(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (test_and_clear_bit(FLG_LASTDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (test_and_clear_bit(FLG_NMD_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u8 zd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) send_mbox(ch->is, SET_DPS(ch->dpath) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ISAR_HIS_SDATA, 0x01, 1, &zd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) } else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) check_send(struct isar_hw *isar, u8 rdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct isar_ch *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) pr_debug("%s: rdm %x\n", isar->name, rdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (rdm & BSTAT_RDM1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ch = sel_bch_isar(isar, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ch->bch.tx_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) isar_fill_fifo(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) send_next(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (rdm & BSTAT_RDM2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ch = sel_bch_isar(isar, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ch->bch.tx_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) isar_fill_fifo(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) send_next(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^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) static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) "300", "600", "1200", "2400", "4800", "7200",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) "9600nt", "9600t", "12000", "14400", "WRONG"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) isar_pump_status_rsp(struct isar_ch *ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) u8 ril = ch->is->buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) u8 rim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!test_and_clear_bit(ISAR_RATE_REQ, &ch->is->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ril > 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) pr_info("%s: wrong pstrsp ril=%d\n", ch->is->name, ril);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ril = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) switch (ch->is->buf[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) rim = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) rim = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) case 0x40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) rim = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) case 0x41:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) rim = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case 0x51:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) rim = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case 0x61:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) rim = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case 0x71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) rim = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case 0x82:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) rim = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case 0x92:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) rim = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case 0xa2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) rim = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) rim = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) sprintf(ch->conmsg, "%s %s", dmril[ril], dmrim[rim]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pr_debug("%s: pump strsp %s\n", ch->is->name, ch->conmsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) isar_pump_statev_modem(struct isar_ch *ch, u8 devt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) u8 dps = SET_DPS(ch->dpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) switch (devt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case PSEV_10MS_TIMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) pr_debug("%s: pump stev TIMER\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) case PSEV_CON_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) pr_debug("%s: pump stev CONNECT\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) case PSEV_CON_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) pr_debug("%s: pump stev NO CONNECT\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) deliver_status(ch, HW_MOD_NOCARR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) case PSEV_V24_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) pr_debug("%s: pump stev V24 OFF\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) case PSEV_CTS_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pr_debug("%s: pump stev CTS ON\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) case PSEV_CTS_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) pr_debug("%s pump stev CTS OFF\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case PSEV_DCD_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) pr_debug("%s: pump stev CARRIER ON\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) case PSEV_DCD_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) pr_debug("%s: pump stev CARRIER OFF\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case PSEV_DSR_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) pr_debug("%s: pump stev DSR ON\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case PSEV_DSR_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) pr_debug("%s: pump stev DSR_OFF\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) case PSEV_REM_RET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) pr_debug("%s: pump stev REMOTE RETRAIN\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case PSEV_REM_REN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) pr_debug("%s: pump stev REMOTE RENEGOTIATE\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case PSEV_GSTN_CLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) u8 dps = SET_DPS(ch->dpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u8 p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) switch (devt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) case PSEV_10MS_TIMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) pr_debug("%s: pump stev TIMER\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) case PSEV_RSP_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pr_debug("%s: pump stev RSP_READY\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ch->state = STFAX_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) deliver_status(ch, HW_MOD_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) #ifdef AUTOCON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (test_bit(BC_FLG_ORIG, &ch->bch.Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) isar_pump_cmd(bch, HW_MOD_FRH, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) isar_pump_cmd(bch, HW_MOD_FTH, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case PSEV_LINE_TX_H:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (ch->state == STFAX_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ch->state = STFAX_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) PCTRL_CMD_CONT, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) pr_debug("%s: pump stev LINE_TX_H wrong st %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ch->is->name, ch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case PSEV_LINE_RX_H:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (ch->state == STFAX_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ch->state = STFAX_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) PCTRL_CMD_CONT, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) pr_debug("%s: pump stev LINE_RX_H wrong st %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ch->is->name, ch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) case PSEV_LINE_TX_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (ch->state == STFAX_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ch->state = STFAX_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) PCTRL_CMD_CONT, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pr_debug("%s: pump stev LINE_TX_B wrong st %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ch->is->name, ch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case PSEV_LINE_RX_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (ch->state == STFAX_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ch->state = STFAX_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) PCTRL_CMD_CONT, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) pr_debug("%s: pump stev LINE_RX_B wrong st %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ch->is->name, ch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case PSEV_RSP_CONN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (ch->state == STFAX_CONT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) pr_debug("%s: pump stev RSP_CONN\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ch->state = STFAX_ACTIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (ch->cmd == PCTRL_CMD_FTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int delay = (ch->mod == 3) ? 1000 : 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* 1s (200 ms) Flags before data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (test_and_set_bit(FLG_FTI_RUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) &ch->bch.Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) del_timer(&ch->ftimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ch->ftimer.expires =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) jiffies + ((delay * HZ) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) test_and_set_bit(FLG_LL_CONN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) add_timer(&ch->ftimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) pr_debug("%s: pump stev RSP_CONN wrong st %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ch->is->name, ch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) case PSEV_FLAGS_DET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) pr_debug("%s: pump stev FLAGS_DET\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) case PSEV_RSP_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) pr_debug("%s: pump stev RSP_DISC state(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ch->is->name, ch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (ch->state == STFAX_ESCAPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) p1 = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) switch (ch->newcmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) ch->state = STFAX_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case PCTRL_CMD_FTM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) p1 = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) case PCTRL_CMD_FTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) PCTRL_CMD_SILON, 1, &p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ch->state = STFAX_SILDET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) case PCTRL_CMD_FRH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) case PCTRL_CMD_FRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ch->mod = ch->newmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) p1 = ch->newmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ch->cmd = ch->newcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ch->cmd, 1, &p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) ch->state = STFAX_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ch->try_mod = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pr_debug("%s: RSP_DISC unknown newcmd %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ch->is->name, ch->newcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) } else if (ch->state == STFAX_ACTIV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (test_and_clear_bit(FLG_LL_OK, &ch->bch.Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) deliver_status(ch, HW_MOD_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) else if (ch->cmd == PCTRL_CMD_FRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) deliver_status(ch, HW_MOD_NOCARR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) deliver_status(ch, HW_MOD_FCERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ch->state = STFAX_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) } else if (ch->state != STFAX_SILDET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* ignore in STFAX_SILDET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ch->state = STFAX_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) deliver_status(ch, HW_MOD_FCERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) case PSEV_RSP_SILDET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) pr_debug("%s: pump stev RSP_SILDET\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (ch->state == STFAX_SILDET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ch->mod = ch->newmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) p1 = ch->newmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ch->cmd = ch->newcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ch->cmd, 1, &p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ch->state = STFAX_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ch->try_mod = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) case PSEV_RSP_SILOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) pr_debug("%s: pump stev RSP_SILOFF\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) case PSEV_RSP_FCERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (ch->state == STFAX_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) pr_debug("%s: pump stev RSP_FCERR try %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) ch->is->name, ch->try_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (ch->try_mod--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ch->cmd, 1, &ch->mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) deliver_status(ch, HW_MOD_FCERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) break;
^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) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) mISDNisar_irq(struct isar_hw *isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct isar_ch *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) get_irq_infos(isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) switch (isar->iis & ISAR_IIS_MSCMSD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) case ISAR_IIS_RDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ch = sel_bch_isar(isar, isar->iis >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) isar_rcv_frame(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) isar->name, isar->iis, isar->cmsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) isar->write_reg(isar->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case ISAR_IIS_GSTEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) isar->write_reg(isar->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) isar->bstat |= isar->cmsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) check_send(isar, isar->cmsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) case ISAR_IIS_BSTEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) #ifdef ERROR_STATISTIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ch = sel_bch_isar(isar, isar->iis >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (isar->cmsb == BSTEV_TBO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ch->bch.err_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (isar->cmsb == BSTEV_RBO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) ch->bch.err_rdo++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) pr_debug("%s: Buffer STEV dpath%d msb(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) isar->name, isar->iis >> 6, isar->cmsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) isar->write_reg(isar->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) case ISAR_IIS_PSTEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) ch = sel_bch_isar(isar, isar->iis >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) rcv_mbox(isar, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (ch->bch.state == ISDN_P_B_MODEM_ASYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) isar_pump_statev_modem(ch, isar->cmsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) else if (ch->bch.state == ISDN_P_B_T30_FAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) isar_pump_statev_fax(ch, isar->cmsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) else if (ch->bch.state == ISDN_P_B_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int tt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) tt = isar->cmsb | 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (tt == 0x3e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) tt = '*';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) else if (tt == 0x3f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) tt = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) else if (tt > '9')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) tt += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) tt |= DTMF_TONE_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) _queue_data(&ch->bch.ch, PH_CONTROL_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) MISDN_ID_ANY, sizeof(tt), &tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) isar->name, ch->bch.state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) isar->cmsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) isar->name, isar->iis, isar->cmsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) isar->write_reg(isar->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) case ISAR_IIS_PSTRSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ch = sel_bch_isar(isar, isar->iis >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) rcv_mbox(isar, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) isar_pump_status_rsp(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) isar->name, isar->iis, isar->cmsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) isar->write_reg(isar->hw, ISAR_IIA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case ISAR_IIS_DIAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) case ISAR_IIS_BSTRSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) case ISAR_IIS_IOM2RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) rcv_mbox(isar, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) case ISAR_IIS_INVMSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) rcv_mbox(isar, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) pr_debug("%s: invalid msg his:%x\n", isar->name, isar->cmsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) rcv_mbox(isar, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) isar->name, isar->iis, isar->cmsb, isar->clsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) EXPORT_SYMBOL(mISDNisar_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ftimer_handler(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct isar_ch *ch = from_timer(ch, t, ftimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) pr_debug("%s: ftimer flags %lx\n", ch->is->name, ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) test_and_clear_bit(FLG_FTI_RUN, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (test_and_clear_bit(FLG_LL_CONN, &ch->bch.Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) setup_pump(struct isar_ch *ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) u8 dps = SET_DPS(ch->dpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) u8 ctrl, param[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) switch (ch->bch.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) case ISDN_P_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) case ISDN_P_B_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) case ISDN_P_B_HDLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) case ISDN_P_B_L2DTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) param[0] = 5; /* TOA 5 db */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) PMOD_DTMF_TRANS, 1, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) param[0] = 40; /* REL -46 dbm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) PMOD_DTMF, 1, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) case ISDN_P_B_MODEM_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ctrl = PMOD_DATAMODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) ctrl |= PCTRL_ORIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) param[5] = PV32P6_CTN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) param[5] = PV32P6_ATN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) param[0] = 6; /* 6 db */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) PV32P2_V22C | PV32P2_V21 | PV32P2_BEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) param[3] = PV32P4_UT144;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) param[4] = PV32P5_UT144;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) case ISDN_P_B_T30_FAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ctrl = PMOD_FAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ctrl |= PCTRL_ORIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) param[1] = PFAXP2_CTN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) param[1] = PFAXP2_ATN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) param[0] = 6; /* 6 db */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ch->state = STFAX_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) test_and_set_bit(FLG_FTI_RUN, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) setup_sart(struct isar_ch *ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) u8 dps = SET_DPS(ch->dpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) u8 ctrl, param[2] = {0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) switch (ch->bch.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) case ISDN_P_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) case ISDN_P_B_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case ISDN_P_B_L2DTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 2, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) case ISDN_P_B_HDLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) case ISDN_P_B_T30_FAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 1, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) case ISDN_P_B_MODEM_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) param[0] = S_P1_CHS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) param[1] = S_P2_BFT_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, ctrl, 2, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) send_mbox(ch->is, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) setup_iom2(struct isar_ch *ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) u8 dps = SET_DPS(ch->dpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) u8 cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (ch->bch.nr == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) msg[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) msg[3] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) switch (ch->bch.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) case ISDN_P_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) cmsb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* dummy slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) msg[1] = ch->dpath + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) msg[3] = ch->dpath + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) case ISDN_P_B_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) case ISDN_P_B_HDLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) case ISDN_P_B_MODEM_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) case ISDN_P_B_T30_FAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) cmsb |= IOM_CTRL_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) case ISDN_P_B_L2DTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (test_bit(FLG_DTMFSEND, &ch->bch.Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) cmsb |= IOM_CTRL_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) cmsb |= IOM_CTRL_ALAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) send_mbox(ch->is, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) send_mbox(ch->is, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) modeisar(struct isar_ch *ch, u32 bprotocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* Here we are selecting the best datapath for requested protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (ch->bch.state == ISDN_P_NONE) { /* New Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) switch (bprotocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) case ISDN_P_NONE: /* init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (!ch->dpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) /* no init for dpath 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) test_and_clear_bit(FLG_HDLC, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) test_and_clear_bit(FLG_TRANSPARENT, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) case ISDN_P_B_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case ISDN_P_B_HDLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) /* best is datapath 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ch->dpath = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) else if (!test_and_set_bit(ISAR_DP1_USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) &ch->is->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ch->dpath = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) pr_info("modeisar both paths in use\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (bprotocol == ISDN_P_B_HDLC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) test_and_set_bit(FLG_HDLC, &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) test_and_set_bit(FLG_TRANSPARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) &ch->bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) case ISDN_P_B_MODEM_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case ISDN_P_B_T30_FAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) case ISDN_P_B_L2DTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /* only datapath 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (!test_and_set_bit(ISAR_DP1_USE, &ch->is->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ch->dpath = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) pr_info("%s: ISAR modeisar analog functions"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) "only with DP1\n", ch->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) pr_info("%s: protocol not known %x\n", ch->is->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) bprotocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) ch->bch.state = bprotocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) setup_pump(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) setup_iom2(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) setup_sart(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (ch->bch.state == ISDN_P_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* Clear resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (ch->dpath == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) test_and_clear_bit(ISAR_DP1_USE, &ch->is->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) else if (ch->dpath == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) test_and_clear_bit(ISAR_DP2_USE, &ch->is->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ch->dpath = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ch->is->ctrl(ch->is->hw, HW_DEACT_IND, ch->bch.nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) ch->is->ctrl(ch->is->hw, HW_ACTIVATE_IND, ch->bch.nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) u8 dps = SET_DPS(ch->dpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) u8 ctrl = 0, nom = 0, p1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ch->is->name, cmd, para, ch->bch.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) case HW_MOD_FTM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (ch->state == STFAX_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) p1 = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) ctrl = PCTRL_CMD_FTM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) nom = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) ch->state = STFAX_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) ch->cmd = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) ch->mod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) ch->try_mod = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) } else if ((ch->state == STFAX_ACTIV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ch->newmod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ch->newcmd = PCTRL_CMD_FTM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) nom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ctrl = PCTRL_CMD_ESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) case HW_MOD_FTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (ch->state == STFAX_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) p1 = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) ctrl = PCTRL_CMD_FTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) nom = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ch->state = STFAX_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) ch->cmd = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) ch->mod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ch->try_mod = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) } else if ((ch->state == STFAX_ACTIV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) ch->newmod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) ch->newcmd = PCTRL_CMD_FTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) nom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) ctrl = PCTRL_CMD_ESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case HW_MOD_FRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (ch->state == STFAX_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) p1 = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) ctrl = PCTRL_CMD_FRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) nom = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) ch->state = STFAX_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) ch->cmd = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) ch->mod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) ch->try_mod = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) } else if ((ch->state == STFAX_ACTIV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ch->newmod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ch->newcmd = PCTRL_CMD_FRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) nom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) ctrl = PCTRL_CMD_ESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) case HW_MOD_FRH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) if (ch->state == STFAX_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) p1 = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) ctrl = PCTRL_CMD_FRH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) nom = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ch->state = STFAX_LINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) ch->cmd = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) ch->mod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) ch->newmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ch->newcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) ch->try_mod = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) } else if ((ch->state == STFAX_ACTIV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) deliver_status(ch, HW_MOD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) ch->newmod = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ch->newcmd = PCTRL_CMD_FRH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) nom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) ctrl = PCTRL_CMD_ESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) ch->state = STFAX_ESCAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) case PCTRL_CMD_TDTMF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) p1 = para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) nom = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) ctrl = PCTRL_CMD_TDTMF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) isar_setup(struct isar_hw *isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) u8 msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /* Dpath 1, 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) msg = 61;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* Buffer Config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) ISAR_HIS_P12CFG, 4, 1, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) isar->ch[i].mml = msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) isar->ch[i].bch.state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) isar->ch[i].dpath = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) modeisar(&isar->ch[i], ISDN_P_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) struct bchannel *bch = container_of(ch, struct bchannel, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) u32 id, *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) switch (hh->prim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) case PH_DATA_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) spin_lock_irqsave(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ret = bchannel_senddata(bch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (ret > 0) { /* direct TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) isar_fill_fifo(ich);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) spin_unlock_irqrestore(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) case PH_ACTIVATE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) spin_lock_irqsave(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) ret = modeisar(ich, ch->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) spin_unlock_irqrestore(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) case PH_DEACTIVATE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) spin_lock_irqsave(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) mISDN_clear_bchannel(bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) modeisar(ich, ISDN_P_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) spin_unlock_irqrestore(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) case PH_CONTROL_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) val = (u32 *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) hh->id, *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) DTMF_TONE_VAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (bch->state == ISDN_P_B_L2DTMF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) char tt = *val & DTMF_TONE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (tt == '*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) tt = 0x1e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) else if (tt == '#')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) tt = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) else if (tt > '9')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) tt -= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) tt &= 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) spin_lock_irqsave(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) spin_unlock_irqrestore(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) pr_info("%s: DTMF send wrong protocol %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) __func__, bch->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) } else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) for (id = 0; id < FAXMODCNT; id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (faxmodulation[id] == *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if ((FAXMODCNT > id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) test_bit(FLG_INITIALIZED, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) pr_debug("%s: isar: new mod\n", ich->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) isar_pump_cmd(ich, hh->id, *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) pr_info("%s: wrong modulation\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) ich->is->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) } else if (hh->id == HW_MOD_LASTDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) test_and_set_bit(FLG_DLEETX, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) pr_info("%s: unknown PH_CONTROL_REQ %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) ich->is->name, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) pr_info("%s: %s unknown prim(%x,%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ich->is->name, __func__, hh->prim, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) return mISDN_ctrl_bchannel(bch, cq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) struct bchannel *bch = container_of(ch, struct bchannel, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) pr_debug("%s: %s cmd:%x %p\n", ich->is->name, __func__, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) case CLOSE_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) test_and_clear_bit(FLG_OPEN, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) cancel_work_sync(&bch->workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) spin_lock_irqsave(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) mISDN_clear_bchannel(bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) modeisar(ich, ISDN_P_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) spin_unlock_irqrestore(ich->is->hwlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) ch->protocol = ISDN_P_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) ch->peer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) module_put(ich->is->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) case CONTROL_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ret = channel_bctrl(bch, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) pr_info("%s: %s unknown prim(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) ich->is->name, __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return ret;
^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) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) free_isar(struct isar_hw *isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) modeisar(&isar->ch[0], ISDN_P_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) modeisar(&isar->ch[1], ISDN_P_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) del_timer(&isar->ch[0].ftimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) del_timer(&isar->ch[1].ftimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) init_isar(struct isar_hw *isar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) int cnt = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) while (cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) isar->version = ISARVersion(isar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) if (isar->ch[0].bch.debug & DEBUG_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) pr_notice("%s: Testing version %d (%d time)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) isar->name, isar->version, 3 - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (isar->version == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) isar->ctrl(isar->hw, HW_RESET_REQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (isar->version != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) timer_setup(&isar->ch[0].ftimer, ftimer_handler, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) test_and_set_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) timer_setup(&isar->ch[1].ftimer, ftimer_handler, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) test_and_set_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) isar_open(struct isar_hw *isar, struct channel_req *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct bchannel *bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (rq->adr.channel == 0 || rq->adr.channel > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (rq->protocol == ISDN_P_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) bch = &isar->ch[rq->adr.channel - 1].bch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) return -EBUSY; /* b-channel can be only open once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) bch->ch.protocol = rq->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) rq->ch = &bch->ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) mISDNisar_init(struct isar_hw *isar, void *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) u32 ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) isar->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) isar->ch[i].bch.nr = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) isar->ch[i].bch.ch.nr = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) isar->ch[i].bch.ch.send = &isar_l2l1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) isar->ch[i].bch.ch.ctrl = isar_bctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) isar->ch[i].bch.hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) isar->ch[i].is = isar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) isar->init = &init_isar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) isar->release = &free_isar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) isar->firmware = &load_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) isar->open = &isar_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) (1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) (1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) (1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) EXPORT_SYMBOL(mISDNisar_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static int __init isar_mod_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) static void __exit isar_mod_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) pr_notice("mISDN: ISAR module unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) module_init(isar_mod_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) module_exit(isar_mod_cleanup);