Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c27b46e7 authored by Karsten Keil's avatar Karsten Keil Committed by David S. Miller
Browse files

mISDN: Implement MISDN_CTRL_RX_OFF for more drivers



MISDN_CTRL_RX_OFF is a meachanism to discard RX data in the driver if
the data is not needed by the application. It can be used when playing
mesages, but not recording or with unidirectional protocols.

Signed-off-by: default avatarKarsten Keil <kkeil@linux-pingi.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6d1ee48f
Loading
Loading
Loading
Loading
+16 −9
Original line number Original line Diff line number Diff line
@@ -408,6 +408,10 @@ hdlc_empty_fifo(struct bchannel *bch, int count)
	struct fritzcard *fc = bch->hw;
	struct fritzcard *fc = bch->hw;


	pr_debug("%s: %s %d\n", fc->name, __func__, count);
	pr_debug("%s: %s %d\n", fc->name, __func__, count);
	if (test_bit(FLG_RX_OFF, &bch->Flags)) {
		p = NULL;
		bch->dropcnt += count;
	} else {
		cnt = bchannel_get_rxbuf(bch, count);
		cnt = bchannel_get_rxbuf(bch, count);
		if (cnt < 0) {
		if (cnt < 0) {
			pr_warning("%s.B%d: No bufferspace for %d bytes\n",
			pr_warning("%s.B%d: No bufferspace for %d bytes\n",
@@ -415,6 +419,7 @@ hdlc_empty_fifo(struct bchannel *bch, int count)
			return;
			return;
		}
		}
		p = skb_put(bch->rx_skb, count);
		p = skb_put(bch->rx_skb, count);
	}
	ptr = (u32 *)p;
	ptr = (u32 *)p;
	if (fc->type == AVM_FRITZ_PCIV2)
	if (fc->type == AVM_FRITZ_PCIV2)
		addr = fc->addr + (bch->nr == 2 ?
		addr = fc->addr + (bch->nr == 2 ?
@@ -426,11 +431,13 @@ hdlc_empty_fifo(struct bchannel *bch, int count)
	cnt = 0;
	cnt = 0;
	while (cnt < count) {
	while (cnt < count) {
		val = le32_to_cpu(inl(addr));
		val = le32_to_cpu(inl(addr));
		if (p) {
			put_unaligned(val, ptr);
			put_unaligned(val, ptr);
			ptr++;
			ptr++;
		}
		cnt += 4;
		cnt += 4;
	}
	}
	if (debug & DEBUG_HW_BFIFO) {
	if (p && (debug & DEBUG_HW_BFIFO)) {
		snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
		snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
			 bch->nr, fc->name, count);
			 bch->nr, fc->name, count);
		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
+6 −3
Original line number Original line Diff line number Diff line
@@ -2224,8 +2224,11 @@ hfcmulti_rx(struct hfc_multi *hc, int ch)
	HFC_wait_nodebug(hc);
	HFC_wait_nodebug(hc);


	/* ignore if rx is off BUT change fifo (above) to start pending TX */
	/* ignore if rx is off BUT change fifo (above) to start pending TX */
	if (hc->chan[ch].rx_off)
	if (hc->chan[ch].rx_off) {
		if (bch)
			bch->dropcnt += poll; /* not exact but fair enough */
		return;
		return;
	}


	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
		f1 = HFC_inb_nodebug(hc, A_F1);
		f1 = HFC_inb_nodebug(hc, A_F1);
@@ -3575,10 +3578,10 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
	switch (cq->op) {
	switch (cq->op) {
	case MISDN_CTRL_GETOP:
	case MISDN_CTRL_GETOP:
		ret = mISDN_ctrl_bchannel(bch, cq);
		ret = mISDN_ctrl_bchannel(bch, cq);
		cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP |
		cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP;
			  MISDN_CTRL_RX_OFF;
		break;
		break;
	case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
	case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
		ret = mISDN_ctrl_bchannel(bch, cq);
		hc->chan[bch->slot].rx_off = !!cq->p1;
		hc->chan[bch->slot].rx_off = !!cq->p1;
		if (!hc->chan[bch->slot].rx_off) {
		if (!hc->chan[bch->slot].rx_off) {
			/* reset fifo on rx on */
			/* reset fifo on rx on */
+5 −0
Original line number Original line Diff line number Diff line
@@ -572,6 +572,11 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
	fcnt_tx = B_FIFO_SIZE - fcnt_tx;
	fcnt_tx = B_FIFO_SIZE - fcnt_tx;
	/* remaining bytes to send (bytes in tx-fifo) */
	/* remaining bytes to send (bytes in tx-fifo) */


	if (test_bit(FLG_RX_OFF, &bch->Flags)) {
		bch->dropcnt += fcnt_rx;
		*z2r = cpu_to_le16(new_z2);
		return;
	}
	maxlen = bchannel_get_rxbuf(bch, fcnt_rx);
	maxlen = bchannel_get_rxbuf(bch, fcnt_rx);
	if (maxlen < 0) {
	if (maxlen < 0) {
		pr_warning("B%d: No bufferspace for %d bytes\n",
		pr_warning("B%d: No bufferspace for %d bytes\n",
+5 −0
Original line number Original line Diff line number Diff line
@@ -842,6 +842,11 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
		hdlc = 1;
		hdlc = 1;
	}
	}
	if (fifo->bch) {
	if (fifo->bch) {
		if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
			fifo->bch->dropcnt += len;
			spin_unlock(&hw->lock);
			return;
		}
		maxlen = bchannel_get_rxbuf(fifo->bch, len);
		maxlen = bchannel_get_rxbuf(fifo->bch, len);
		rx_skb = fifo->bch->rx_skb;
		rx_skb = fifo->bch->rx_skb;
		if (maxlen < 0) {
		if (maxlen < 0) {
+5 −0
Original line number Original line Diff line number Diff line
@@ -936,6 +936,11 @@ hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
	int maxlen;
	int maxlen;


	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
	if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
		hscx->bch.dropcnt += count;
		hscx_cmdr(hscx, 0x80); /* RMC */
		return;
	}
	maxlen = bchannel_get_rxbuf(&hscx->bch, count);
	maxlen = bchannel_get_rxbuf(&hscx->bch, count);
	if (maxlen < 0) {
	if (maxlen < 0) {
		hscx_cmdr(hscx, 0x80); /* RMC */
		hscx_cmdr(hscx, 0x80); /* RMC */
Loading