1921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/*
2921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * SBE 2T3E3 synchronous serial card driver for Linux
3921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa *
4921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
5921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa *
6921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * This program is free software; you can redistribute it and/or modify it
7921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * under the terms of version 2 of the GNU General Public License
8921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * as published by the Free Software Foundation.
9921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa *
10921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * This code is based on a driver written by SBE Inc.
11921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa */
12921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
13921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include <linux/hdlc.h>
14921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include <linux/interrupt.h>
15921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include <linux/netdevice.h>
16921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include "2t3e3.h"
17921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
18921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasairqreturn_t t3e3_intr(int irq, void *dev_instance)
19921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
20921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	struct channel *sc = dev_to_priv(dev_instance);
21921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 val;
22921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	irqreturn_t ret = IRQ_NONE;
23921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
24921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	sc->interrupt_active = 1;
25921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
26921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	val = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR);
27921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
28921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (val & SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE) {
29921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev,
30921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			"Rx LOS Chng Int r=%02x (LOS|OOF=%02x)\n",
31921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			val, (sc->s.LOS << 4) | sc->s.OOF);
32921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		cpld_LOS_update(sc);
33921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		ret = IRQ_HANDLED;
34921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
35921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
36921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED) {
37921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_intr(sc);
38921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		ret = IRQ_HANDLED;
39921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
40921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
41921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED) {
42921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		exar7250_intr(sc);
43921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		ret = IRQ_HANDLED;
44921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
45921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
46921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/*
47921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	  we don't care about other interrupt sources (DMO, LOS, LCV) because
48921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	  they are handled by Framer too
49921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	*/
50921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
51921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	sc->interrupt_active = 0;
52921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return ret;
53921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
54921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
55921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid dc_intr(struct channel *sc)
56921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
57921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 val;
58921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
59921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* disable ethernet interrupts */
60921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* grrr this clears interrupt summary bits !!! */
61921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
62921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
63921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	while ((val = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS)) &
64921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	       (SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED |
65921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
66921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
67921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW |
68921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
69921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED |
70921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)) {
71921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, val);
72921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
73921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Ethernet controller interrupt! (CSR5 = %08X)\n",
74921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			val);
75921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
76921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (val & (SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
77921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			   SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
78921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			   SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)) {
79921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (val & SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT)
80921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
81921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Receive interrupt (LOS=%d, OOF=%d)\n",
82921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.LOS, sc->s.OOF);
83921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (val & SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE)
84921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
85921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Receive buffer unavailable\n");
86921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (val & SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)
87921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
88921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Receive process stopped\n");
89921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dc_intr_rx(sc);
90921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
91921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
92921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (val & SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW) {
93921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev, "Transmit underflow\n");
94921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dc_intr_tx_underflow(sc);
95921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
96921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
97921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (val & (SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
98921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			   SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT |
99921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			   SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)) {
100921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (val & SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)
101921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev, "Transmit interrupt\n");
102921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (val & SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE)
103921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
104921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Transmit buffer unavailable\n");
105921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (val & SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)
106921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
107921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Transmit process stopped\n");
108921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dc_intr_tx(sc);
109921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
110921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
111921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
112921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* enable ethernet interrupts */
113921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
114921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 sc->ether.interrupt_enable_mask);
115921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
116921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
117921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid dc_intr_rx(struct channel *sc)
118921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
119921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 current_read;
120921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 error_mask, error;
121921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	t3e3_rx_desc_t *current_desc;
122921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	struct sk_buff *m, *m2;
123921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned rcv_len;
124921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
125921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	sc->rcv_count++; /* for the activity LED */
126921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
127921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	current_read = sc->ether.rx_ring_current_read;
128921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dev_dbg(&sc->pdev->dev, "intr_rx current_read = %d\n", current_read);
129921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
130921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* when ethernet loopback is set, ignore framer signals */
131921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if ((sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) && sc->s.OOF) {
132921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		while (!(sc->ether.rx_ring[current_read].rdes0 &
133921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			 SBE_2T3E3_RX_DESC_21143_OWN)) {
134921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_desc = &sc->ether.rx_ring[current_read];
135921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
136921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
137921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_desc->rdes1 |= SBE_2T3E3_MTU;
138921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
139921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
140921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
141921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		sc->ether.rx_ring_current_read = current_read;
142921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		return;
143921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
144921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
145921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	while (!(sc->ether.rx_ring[current_read].rdes0 &
146921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_RX_DESC_21143_OWN)) {
147921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc = &sc->ether.rx_ring[current_read];
148921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
149921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev, "rdes0: %08X        rdes1: %08X\n",
150921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_desc->rdes0, current_desc->rdes1);
151921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
152921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		m = sc->ether.rx_data[current_read];
153921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		rcv_len = (current_desc->rdes0 & SBE_2T3E3_RX_DESC_FRAME_LENGTH) >>
154921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT;
155921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
156921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev, "mbuf was received (mbuf len = %d)\n",
157921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			rcv_len);
158921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
159921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		switch (sc->p.crc) {
160921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		case SBE_2T3E3_CRC_16:
161921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			rcv_len -= SBE_2T3E3_CRC16_LENGTH;
162921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			break;
163921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		case SBE_2T3E3_CRC_32:
164921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			rcv_len -= SBE_2T3E3_CRC32_LENGTH;
165921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			break;
166921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		default:
167921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			break;
168921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
169921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
170921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (current_desc->rdes0 & SBE_2T3E3_RX_DESC_LAST_DESC) {
171921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
172921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			/* TODO: is collision possible? */
173921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			error_mask = SBE_2T3E3_RX_DESC_DESC_ERROR |
174921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_RX_DESC_COLLISION_SEEN |
175921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_RX_DESC_DRIBBLING_BIT;
176921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
177921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			switch (sc->p.frame_mode) {
178921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			case SBE_2T3E3_FRAME_MODE_HDLC:
179921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				error_mask |= SBE_2T3E3_RX_DESC_MII_ERROR;
180921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (sc->p.crc == SBE_2T3E3_CRC_32)
181921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					error_mask |= SBE_2T3E3_RX_DESC_CRC_ERROR;
182921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				break;
183921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
184921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			case SBE_2T3E3_FRAME_MODE_RAW:
185921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				break;
186921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			default:
187921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				error_mask = 0;
188921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
189921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
190921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (sc->s.LOS) {
191921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT ||
192921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						SBE_2T3E3_RX_DESC_MII_ERROR);
193921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
194921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
195921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			error = current_desc->rdes0 & error_mask;
196921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (error) {
197921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.in_errors++;
198921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
199921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"error interrupt: NO_ERROR_MESSAGE = %d\n",
200921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES ? 1 : 0);
201921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
202921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
203921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
204921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				current_desc->rdes1 |= SBE_2T3E3_MTU;
205921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
206921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
207921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (error & SBE_2T3E3_RX_DESC_DESC_ERROR) {
208921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
209921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						dev_err(&sc->pdev->dev,
210921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa							"SBE 2T3E3: descriptor error\n");
211921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.in_error_desc++;
212921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
213921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
214921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (error & SBE_2T3E3_RX_DESC_COLLISION_SEEN) {
215921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
216921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						dev_err(&sc->pdev->dev,
217921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa							"SBE 2T3E3: collision seen\n");
218921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.in_error_coll++;
219921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				} else {
220921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					if (error & SBE_2T3E3_RX_DESC_DRIBBLING_BIT) {
221921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
222921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa							dev_err(&sc->pdev->dev,
223921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa								"SBE 2T3E3: dribbling bits error\n");
224921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						sc->s.in_error_drib++;
225921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					}
226921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
227921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					if (error & SBE_2T3E3_RX_DESC_CRC_ERROR) {
228921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
229921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa							dev_err(&sc->pdev->dev,
230921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa								"SBE 2T3E3: crc error\n");
231921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						sc->s.in_error_crc++;
232921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					}
233921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
234921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
235921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (error & SBE_2T3E3_RX_DESC_MII_ERROR) {
236921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
237921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						dev_err(&sc->pdev->dev, "SBE 2T3E3: mii error\n");
238921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.in_error_mii++;
239921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
240921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
241921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
242921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->r.flags |= SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
243921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				continue;
244921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
245921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
246921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
247921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
248921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
249921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc->rdes1 |= SBE_2T3E3_MTU;
250921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
251921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (rcv_len > 1600) {
252921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.in_errors++;
253921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.in_dropped++;
254921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
255921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_err(&sc->pdev->dev, "SBE 2T3E3: oversized rx: rdes0 = %08X\n",
256921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					current_desc->rdes0);
257921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		} else {
258921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			m2 = dev_alloc_skb(MCLBYTES);
259921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (m2 != NULL) {
260921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				current_desc->rdes2 = virt_to_phys(m2->data);
261921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->ether.rx_data[current_read] = m2;
262921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.in_packets++;
263921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.in_bytes += rcv_len;
264921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				m->dev = sc->dev;
265921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				skb_put(m, rcv_len);
266921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				skb_reset_mac_header(m);
267921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				m->protocol = hdlc_type_trans(m, m->dev);
268921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				netif_rx(m);
269921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
270921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				/* good packet was received so we will show error messages again... */
271921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES) {
272921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					dev_dbg(&sc->pdev->dev,
273921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa						"setting ERROR_MESSAGES->0\n");
274921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->r.flags &= ~SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
275921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
276921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
277921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			} else {
278921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.in_errors++;
279921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.in_dropped++;
280921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
281921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
282921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
283921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
284921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
285921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
286921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	sc->ether.rx_ring_current_read = current_read;
287921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
288921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
289921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
290921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
291921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid dc_intr_tx(struct channel *sc)
292921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
293921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 current_read, current_write;
294921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 last_segment, error;
295921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	t3e3_tx_desc_t *current_desc;
296921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
297921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock(&sc->ether.tx_lock);
298921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
299921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	current_read = sc->ether.tx_ring_current_read;
300921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	current_write = sc->ether.tx_ring_current_write;
301921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
302921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	while (current_read != current_write) {
303921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc = &sc->ether.tx_ring[current_read];
304921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
305921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (current_desc->tdes0 & SBE_2T3E3_RX_DESC_21143_OWN)
306921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			break;
307921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
308921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev,
309921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			"txeof: tdes0 = %08X        tdes1 = %08X\n",
310921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_desc->tdes0, current_desc->tdes1);
311921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
312921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		error = current_desc->tdes0 & (SBE_2T3E3_TX_DESC_ERROR_SUMMARY |
313921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					       SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT |
314921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					       SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER |
315921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					       SBE_2T3E3_TX_DESC_NO_CARRIER |
316921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					       SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT |
317921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					       SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR |
318921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					       SBE_2T3E3_TX_DESC_DEFFERED);
319921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
320921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		last_segment = current_desc->tdes1 & SBE_2T3E3_TX_DESC_LAST_SEGMENT;
321921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
322921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc->tdes0 = 0;
323921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc->tdes1 &= SBE_2T3E3_TX_DESC_END_OF_RING |
324921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
325921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_desc->tdes2 = 0;
326921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		sc->ether.tx_free_cnt++;
327921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
328921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (last_segment != SBE_2T3E3_TX_DESC_LAST_SEGMENT) {
329921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
330921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			continue;
331921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
332921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
333921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
334921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (sc->ether.tx_data[current_read]) {
335921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.out_packets++;
336921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.out_bytes += sc->ether.tx_data[current_read]->len;
337921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_kfree_skb_any(sc->ether.tx_data[current_read]);
338921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->ether.tx_data[current_read] = NULL;
339921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
340921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
341921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (error > 0) {
342921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.out_errors++;
343921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
344921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (error & SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT) {
345921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_err(&sc->pdev->dev, "SBE 2T3E3: transmit jabber timeout\n");
346921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.out_error_jab++;
347921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
348921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
349921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) {
350921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (error & SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER) {
351921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					dev_err(&sc->pdev->dev, "SBE 2T3E3: loss of carrier\n");
352921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.out_error_lost_carr++;
353921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
354921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
355921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				if (error & SBE_2T3E3_TX_DESC_NO_CARRIER) {
356921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					dev_err(&sc->pdev->dev, "SBE 2T3E3: no carrier\n");
357921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.out_error_no_carr++;
358921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
359921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
360921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
361921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (error & SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT) {
362921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_err(&sc->pdev->dev, "SBE 2T3E3: link fail report\n");
363921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.out_error_link_fail++;
364921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
365921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
366921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (error & SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR) {
367921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_err(&sc->pdev->dev, "SBE 2T3E3:"
368921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					" transmission underflow error\n");
369921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.out_error_underflow++;
370921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				spin_unlock(&sc->ether.tx_lock);
371921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
372921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dc_restart(sc);
373921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				return;
374921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
375921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
376921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (error & SBE_2T3E3_TX_DESC_DEFFERED) {
377921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_err(&sc->pdev->dev, "SBE 2T3E3: transmission deferred\n");
378921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.out_error_dereferred++;
379921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
380921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
381921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
382921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
383921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
384921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
385921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	sc->ether.tx_ring_current_read = current_read;
386921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
387921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Relieve flow control when the TX queue is drained at least half way */
388921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (sc->ether.tx_full &&
389921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	    (sc->ether.tx_free_cnt >= (SBE_2T3E3_TX_DESC_RING_SIZE / 2))) {
390921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		sc->ether.tx_full = 0;
391921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		netif_wake_queue(sc->dev);
392921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
393921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock(&sc->ether.tx_lock);
394921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
395921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
396921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
397921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid dc_intr_tx_underflow(struct channel *sc)
398921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
399921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 val;
400921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
401921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
402921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
403921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE);
404921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
405921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		      SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS);
406921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
407921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	switch (val & SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS) {
408921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1:
409921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
410921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			    SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2);
411921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
412921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2:
413921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
414921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			    SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3);
415921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
416921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3:
417921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
418921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			    SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4);
419921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
420921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4:
421921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	default:
422921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
423921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			    SBE_2T3E3_21143_VAL_STORE_AND_FORWARD);
424921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
425921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
426921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
427921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_transmitter_onoff(sc, SBE_2T3E3_ON);
428921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
429921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
430921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
431921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
432921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
433921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid exar7250_intr(struct channel *sc)
434921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
435921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 status, old_OOF;
436921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
437921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
438921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* disable interrupts */
439921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
440921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
441921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
442921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	old_OOF = sc->s.OOF;
443921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
444921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
445921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt! (REG[0x05] = %02X)\n", status);
446921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
447921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	switch (sc->p.frame_type) {
448921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_FRAME_TYPE_E3_G751:
449921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_FRAME_TYPE_E3_G832:
450921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		exar7250_E3_intr(sc, status);
451921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
452921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
453921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
454921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_FRAME_TYPE_T3_M13:
455921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		exar7250_T3_intr(sc, status);
456921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
457921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
458921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	default:
459921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
460921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
461921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
462921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (sc->s.OOF != old_OOF) {
463921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (sc->s.OOF) {
464921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
465921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Disabling eth interrupts\n");
466921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				/* turn off ethernet interrupts */
467921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dc_stop_intr(sc);
468921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
469921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		} else if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
470921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Enabling eth interrupts\n");
471921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			/* start interrupts */
472921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.OOF = 1;
473921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dc_intr_rx(sc);
474921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			sc->s.OOF = 0;
475921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (sc->p.receiver_on) {
476921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dc_receiver_onoff(sc, SBE_2T3E3_OFF);
477921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dc_receiver_onoff(sc, SBE_2T3E3_ON);
478921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
479921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dc_start_intr(sc);
480921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
481921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
482921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
483921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* reenable interrupts */
484921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
485921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		       SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
486921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		       SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE
487921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		);
488921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
489921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
490921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
491921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
492921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid exar7250_T3_intr(struct channel *sc, u32 block_status)
493921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
494921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 status, result;
495921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
496921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
497921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
498921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
499921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (status) {
500921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev,
501921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				"Framer interrupt T3 RX (REG[0x13] = %02X)\n",
502921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				status);
503921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
504921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
505921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
506921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
507921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS) {
508921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
509921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Framer interrupt T3: LOS\n");
510921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
511921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
512921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
513921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#else
514921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			cpld_LOS_update(sc);
515921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
516921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS) {
517921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
518921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
519921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Framer interrupt T3: OOF (%d)\n",
520921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.OOF);
521921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
522921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
523921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
524921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
525921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
526921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
527921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE |
528921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
529921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE |
530921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE |
531921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE |
532921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE |
533921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE |
534921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE
535921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
536921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
537921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
538921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
539921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (status) {
540921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev,
541921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				"Framer interrupt T3 RX (REG[0x17] = %02X)\n",
542921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				status);
543921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
544921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS,
545921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE |
546921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE
547921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				);
548921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
549921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
550921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
551921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
552921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (status)
553921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev,
554921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				"Framer interrupt T3 RX (REG[0x18] = %02X)\n",
555921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				status);
556921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
557921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
558921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
559921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
560921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
561921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x31] = %02X)\n",
562921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			status);
563921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
564921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
565921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x34] = %02X)\n",
566921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			status);
567921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
568921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
569921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
570921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
571921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid exar7250_E3_intr(struct channel *sc, u32 block_status)
572921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
573921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 status, result;
574921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
575921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
576921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
577921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
578921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (status) {
579921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev,
580921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				"Framer interrupt E3 RX (REG[0x14] = %02X)\n",
581921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				status);
582921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
583921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
584921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
585921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
586921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS) {
587921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
588921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Framer interrupt E3: LOS\n");
589921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
590921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
591921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#else
592921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			cpld_LOS_update(sc);
593921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
594921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS) {
595921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
596921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				dev_dbg(&sc->pdev->dev,
597921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					"Framer interrupt E3: OOF (%d)\n",
598921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa					sc->s.OOF);
599921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			}
600921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
601921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
602921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
603921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE
604921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				);
605921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
606921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE |
607921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
608921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE |
609921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE |
610921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE
611921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
612921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				}
613921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
614921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
615921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		if (status) {
616921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			dev_dbg(&sc->pdev->dev,
617921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				"Framer interrupt E3 RX (REG[0x15] = %02X)\n",
618921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				status);
619921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
620921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
621921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2,
622921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE |
623921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE |
624921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa				       SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE);
625921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
626921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		}
627921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
628921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
629921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
630921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
631921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
632921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt E3 TX (REG[0x34] = %02X)\n",
633921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			status);
634921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
635921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
636