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