^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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author Karsten Keil <kkeil@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2008 by Karsten Keil <kkeil@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mISDNhw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) dchannel_bh(struct work_struct *ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct dchannel *dch = container_of(ws, struct dchannel, workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (test_and_clear_bit(FLG_RECVQUEUE, &dch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) while ((skb = skb_dequeue(&dch->rqueue))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (likely(dch->dev.D.peer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) err = dch->dev.D.recv(dch->dev.D.peer, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (test_and_clear_bit(FLG_PHCHANGE, &dch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (dch->phfunc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) dch->phfunc(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) bchannel_bh(struct work_struct *ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct bchannel *bch = container_of(ws, struct bchannel, workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) while ((skb = skb_dequeue(&bch->rqueue))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) bch->rcount--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (likely(bch->ch.peer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) err = bch->ch.recv(bch->ch.peer, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) test_and_set_bit(FLG_HDLC, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ch->maxlen = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ch->hw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ch->phfunc = phf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) skb_queue_head_init(&ch->squeue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) skb_queue_head_init(&ch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) INIT_LIST_HEAD(&ch->dev.bchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) INIT_WORK(&ch->workq, dchannel_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) EXPORT_SYMBOL(mISDN_initdchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned short minlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ch->Flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ch->minlen = minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ch->next_minlen = minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ch->init_minlen = minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ch->maxlen = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ch->next_maxlen = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ch->init_maxlen = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ch->hw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) skb_queue_head_init(&ch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ch->rcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ch->next_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) INIT_WORK(&ch->workq, bchannel_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) EXPORT_SYMBOL(mISDN_initbchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mISDN_freedchannel(struct dchannel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (ch->tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) dev_kfree_skb(ch->tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (ch->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dev_kfree_skb(ch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) skb_queue_purge(&ch->squeue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) skb_queue_purge(&ch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) flush_work(&ch->workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) EXPORT_SYMBOL(mISDN_freedchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mISDN_clear_bchannel(struct bchannel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ch->tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_kfree_skb(ch->tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (ch->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev_kfree_skb(ch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ch->next_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) dev_kfree_skb(ch->next_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ch->next_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) test_and_clear_bit(FLG_RX_OFF, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ch->dropcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ch->minlen = ch->init_minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ch->next_minlen = ch->init_minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ch->maxlen = ch->init_maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ch->next_maxlen = ch->init_maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) skb_queue_purge(&ch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ch->rcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) EXPORT_SYMBOL(mISDN_clear_bchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mISDN_freebchannel(struct bchannel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) cancel_work_sync(&ch->workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mISDN_clear_bchannel(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) EXPORT_SYMBOL(mISDN_freebchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) switch (cq->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case MISDN_CTRL_GETOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) MISDN_CTRL_RX_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case MISDN_CTRL_FILL_EMPTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (cq->p1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case MISDN_CTRL_RX_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* read back dropped byte count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) cq->p2 = bch->dropcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (cq->p1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) test_and_set_bit(FLG_RX_OFF, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) test_and_clear_bit(FLG_RX_OFF, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) bch->dropcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case MISDN_CTRL_RX_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) bch->next_maxlen = cq->p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) bch->next_minlen = cq->p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* we return the old values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) cq->p1 = bch->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) cq->p2 = bch->maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) pr_info("mISDN unhandled control %x operation\n", cq->op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) EXPORT_SYMBOL(mISDN_ctrl_bchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static inline u_int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) get_sapi_tei(u_char *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u_int sapi, tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) sapi = *p >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) tei = p[1] >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return sapi | (tei << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) recv_Dchannel(struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct mISDNhead *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (dch->rx_skb->len < 2) { /* at least 2 for sapi / tei */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) dev_kfree_skb(dch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) hh = mISDN_HEAD_P(dch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) hh->prim = PH_DATA_IND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) hh->id = get_sapi_tei(dch->rx_skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) skb_queue_tail(&dch->rqueue, dch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) dch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) schedule_event(dch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) EXPORT_SYMBOL(recv_Dchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) recv_Echannel(struct dchannel *ech, struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct mISDNhead *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ech->rx_skb->len < 2) { /* at least 2 for sapi / tei */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_kfree_skb(ech->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ech->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) hh = mISDN_HEAD_P(ech->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) hh->prim = PH_DATA_E_IND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) hh->id = get_sapi_tei(ech->rx_skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) skb_queue_tail(&dch->rqueue, ech->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ech->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) schedule_event(dch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) EXPORT_SYMBOL(recv_Echannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) recv_Bchannel(struct bchannel *bch, unsigned int id, bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct mISDNhead *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* if allocation did fail upper functions still may call us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (unlikely(!bch->rx_skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (unlikely(!bch->rx_skb->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* we have no data to send - this may happen after recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * from overflow or too small allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * We need to free the buffer here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dev_kfree_skb(bch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) bch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (test_bit(FLG_TRANSPARENT, &bch->Flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) (bch->rx_skb->len < bch->minlen) && !force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) hh = mISDN_HEAD_P(bch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) hh->prim = PH_DATA_IND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) hh->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (bch->rcount >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) "B%d receive queue overflow - flushing!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) bch->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) skb_queue_purge(&bch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bch->rcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) skb_queue_tail(&bch->rqueue, bch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) bch->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) schedule_event(bch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) EXPORT_SYMBOL(recv_Bchannel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) recv_Dchannel_skb(struct dchannel *dch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) skb_queue_tail(&dch->rqueue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) schedule_event(dch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) EXPORT_SYMBOL(recv_Dchannel_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (bch->rcount >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) printk(KERN_WARNING "B-channel %p receive queue overflow, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) "flushing!\n", bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) skb_queue_purge(&bch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bch->rcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) bch->rcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) skb_queue_tail(&bch->rqueue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) schedule_event(bch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) EXPORT_SYMBOL(recv_Bchannel_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) confirm_Dsend(struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) printk(KERN_ERR "%s: no skb id %x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) mISDN_HEAD_ID(dch->tx_skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) skb_queue_tail(&dch->rqueue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) schedule_event(dch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) get_next_dframe(struct dchannel *dch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) dch->tx_skb = skb_dequeue(&dch->squeue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (dch->tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) confirm_Dsend(dch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) dch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) EXPORT_SYMBOL(get_next_dframe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) confirm_Bsend(struct bchannel *bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (bch->rcount >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) printk(KERN_WARNING "B-channel %p receive queue overflow, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) "flushing!\n", bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) skb_queue_purge(&bch->rqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) bch->rcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) printk(KERN_ERR "%s: no skb id %x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) mISDN_HEAD_ID(bch->tx_skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) bch->rcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) skb_queue_tail(&bch->rqueue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) schedule_event(bch, FLG_RECVQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) get_next_bframe(struct bchannel *bch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) bch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) bch->tx_skb = bch->next_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (bch->tx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) bch->next_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* confirm imediately to allow next data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) confirm_Bsend(bch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) printk(KERN_WARNING "B TX_NEXT without skb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) bch->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) EXPORT_SYMBOL(get_next_bframe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) queue_ch_frame(struct mISDNchannel *ch, u_int pr, int id, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct mISDNhead *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) _queue_data(ch, pr, id, 0, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ch->peer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) hh->prim = pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) hh->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (!ch->recv(ch->peer, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) EXPORT_SYMBOL(queue_ch_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dchannel_senddata(struct dchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* check oversize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (skb->len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) printk(KERN_WARNING "%s: skb too small\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (skb->len > ch->maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) __func__, skb->len, ch->maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* HW lock must be obtained */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) skb_queue_tail(&ch->squeue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* write to fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ch->tx_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) EXPORT_SYMBOL(dchannel_senddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) bchannel_senddata(struct bchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* check oversize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (skb->len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) printk(KERN_WARNING "%s: skb too small\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (skb->len > ch->maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) __func__, skb->len, ch->maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* HW lock must be obtained */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* check for pending next_skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (ch->next_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) __func__, skb->len, ch->next_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) test_and_set_bit(FLG_TX_NEXT, &ch->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ch->next_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* write to fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ch->tx_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ch->tx_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) confirm_Bsend(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) EXPORT_SYMBOL(bchannel_senddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* The function allocates a new receive skb on demand with a size for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * requirements of the current protocol. It returns the tailroom of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * receive skb or an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) bchannel_get_rxbuf(struct bchannel *bch, int reqlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (bch->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) len = skb_tailroom(bch->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (len < reqlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pr_warn("B%d no space for %d (only %d) bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) bch->nr, reqlen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* send what we have now and try a new buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) recv_Bchannel(bch, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* on HDLC we have to drop too big frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* update current min/max length first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (unlikely(bch->maxlen != bch->next_maxlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) bch->maxlen = bch->next_maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (unlikely(bch->minlen != bch->next_minlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) bch->minlen = bch->next_minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (unlikely(reqlen > bch->maxlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (reqlen >= bch->minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) len = reqlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) len = 2 * bch->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (len > bch->maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) len = bch->maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* with HDLC we do not know the length yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) len = bch->maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!bch->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) pr_warn("B%d receive no memory for %d bytes\n", bch->nr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) len = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) EXPORT_SYMBOL(bchannel_get_rxbuf);