Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);