1/*	$NetBSD: if_eca_fiq.S,v 1.1 2002/03/24 15:47:16 bjh21 Exp $	*/
2
3/*-
4 * Copyright (c) 2001 Ben Harris
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <machine/asm.h>
31
32RCSID("$NetBSD: if_eca_fiq.S,v 1.1 2002/03/24 15:47:16 bjh21 Exp $")
33
34#include <dev/ic/mc6854reg.h>
35#include <arch/acorn26/ioc/if_ecavar.h>
36
37#include "assym.h"
38
39ENTRY_NP(eca_fiqhandler)
40	ldr	pc, [r11, #EFS_FIQHANDLER]
41	.global	eca_efiqhandler
42_C_LABEL(eca_efiqhandler):
43
44/*
45 * Econet Rx FIQ handler registers:
46 * R8:  Address of 6854
47 * R9:  Data buffer address
48 * R10: Space left in buffer
49 * R11: struct eca_fiqstate pointer
50 * R12: Scratch
51 * R13: Scratch
52 */
53
54ENTRY(eca_fiqhandler_rx)
55	/* If there's something in the Rx FIFO, read it now. */
56	ldrb	r12, [r8, #(MC6854_SR2 << 2)]
57	tst	r12, #MC6854_SR2_OVRN
58	bne	Leca_rx_nodata
59	tst	r12, #MC6854_SR2_RDA
60	beq	Leca_rx_nodata
61Leca_rx_loop:
62	ldrb	r12, [r8, #(MC6854_RXFIFO << 2)]
63	strb	r12, [r9], #1
64	subs	r10, r10, #1
65	beq	Leca_rx_counter		/* Rx buffer full */
66	ldrb	r12, [r8, #(MC6854_SR2 << 2)]
67	tst	r12, #MC6854_SR2_RDA	/* More data? */
68	bne	Leca_rx_loop
69Leca_rx_nodata:
70	teq	r12, #0			/* No more status? */
71	subeqs	pc, r14, #4		/* Return. */
72	tst	r12, #MC6854_SR2_FV	/* End of frame? */
73	ldrne	r12, [r11, #EFS_RX_FLAGS]
74	tstne	r12, #ERXF_FLAGFILL	/* Want flag fill? */
75	movne	r12, #(MC6854_CR2_RTS | MC6854_CR2_F_M_IDLE)
76	strneb	r12, [r8, #(MC6854_CR2 << 2)]
77	b	fiq_downgrade
78
79Leca_rx_counter:
80	/* If we've already got the header, this indicates end-of-buffer. */
81	ldr	r12, [r11, #EFS_RX_FLAGS]
82	tst	r12, #ERXF_GOTHDR
83	bne	Leca_rx_full
84	ldrb	r12, [r9, #-2]
85	ldrb	r13, [r11, #EFS_RX_MYADDR]
86	teq	r12, r13		/* Our host */
87	ldreqb	r12, [r9, #-1]
88	teqeq	r12, #0			/* Local network? */
89	ldr	r12, [r11, #EFS_RX_FLAGS]
90	orrne	r12, r12, #ERXF_GOTHDR
91	orreq	r12, r12, #(ERXF_GOTHDR | ERXF_FLAGFILL)
92	str	r12, [r11, #EFS_RX_FLAGS]
93	ldr	r12, [r11, #EFS_RX_CURMBUF]
94	ldr	r10, [r12, #M_LEN]
95	ldr	r12, [r12, #M_DATA]
96	sub	r12, r9, r12		/* Amount got already */
97	sub	r10, r10, r12
98	subs	pc, r14, #4
99
100Leca_rx_full:
101	/* Rx buffer full.  See if there's another mbuf in the chain. */
102	ldr	r12, [r11, #EFS_RX_CURMBUF]
103	ldr	r12, [r12, #M_NEXT]
104	str	r12, [r11, #EFS_RX_CURMBUF]
105	teq	r12, #0
106	beq	fiq_downgrade
107	ldr	r9, [r12, #M_DATA]
108	ldr	r10, [r12, #M_LEN]
109	subs	pc, r14, #4
110
111/*
112 * Econet Tx FIQ handler registers:
113 * R8:  Address of 6854
114 * R9:  Data buffer address
115 * R10: Data left in buffer
116 * R11: struct eca_fiqstate pointer
117 * R12: Scratch
118 * R13: Scratch
119 */
120ENTRY(eca_fiqhandler_tx)
121	ldrb	r12, [r8, #(MC6854_SR1 << 2)]
122	tst	r12, #MC6854_SR1_TDRA
123	beq	Leca_tx_nospace
124Leca_tx_loop:
125	ldrb	r12, [r9], #1
126	strb	r12, [r8, #(MC6854_TXFIFOFC << 2)]
127	subs	r10, r10, #1
128	beq	Leca_tx_nodata
129	ldrb	r12, [r8, #(MC6854_SR1 << 2)]
130	tst	r12, #MC6854_SR1_TDRA
131	bne	Leca_tx_loop
132Leca_tx_nospace:
133	tst	r12, #MC6854_SR1_IRQ	/* No more status? */
134	subeqs	pc, r14, #4		/* Return. */
135	b	fiq_downgrade
136
137Leca_tx_nodata:
138	/* We get here when the current data block is empty. */
139	ldr	r12, [r11, #EFS_TX_CURMBUF]
140	ldr	r12, [r12, #M_NEXT]
141	str	r12, [r11, #EFS_TX_CURMBUF]
142	teq	r12, #0				/* Another mbuf? */
143	beq	Leca_tx_endofframe
144	ldr	r9, [r12, #M_DATA]		/* Line up next mbuf. */
145	ldr	r10, [r12, #M_LEN]
146	subs	pc, r14, #4
147
148Leca_tx_endofframe:
149	mov	r12, #(MC6854_CR2_TX_LAST)	/* If not, finish frame... */
150	strb	r12, [r8, #(MC6854_CR2 << 2)]
151	/* Code equivalent to parts of eca_init_rx_hard() */
152	adr	r12, _C_LABEL(eca_fiqhandler_rx)
153	str	r12, [r11, #(EFS_FIQHANDLER)]
154	mov	r12, #(MC6854_CR1_RIE)
155	strb	r12, [r8, #(MC6854_CR1 << 2)]
156	add	r12, r11, #(EFS_RX_FIQREGS)
157	ldmia	r12, {r8-r11}
158	/* End code equivalent to parts of eca_init_rx_hard() */
159	b	fiq_downgrade_dont_disable	/* ... and report back. */
160