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