2019-05-28 20:10:09 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2005-04-17 02:20:36 +04:00
.psize 0
/ *
wanXL s e r i a l c a r d d r i v e r f o r L i n u x
card f i r m w a r e p a r t
Copyright ( C ) 2 0 0 3 K r z y s z t o f H a l a s a < k h c @pm.waw.pl>
DPRAM B D s :
0 x0 0 0 - 0 x05 0 T X #0 0 x05 0 - 0 x14 0 R X #0
0 x1 4 0 - 0 x19 0 T X #1 0 x19 0 - 0 x28 0 R X #1
0 x2 8 0 - 0 x2 D 0 T X #2 0 x2 D 0 - 0 x3 C 0 R X #2
0 x3 C 0 - 0 x41 0 T X #3 0 x41 0 - 0 x50 0 R X #3
0 0 0 5 FF 1 5 3 6 B y t e s D u a l - P o r t R A M U s e r D a t a / B D s
6 0 0 6 FF 2 5 6 B y t e s D u a l - P o r t R A M U s e r D a t a / B D s
7 0 0 7 FF 2 5 6 B y t e s D u a l - P o r t R A M U s e r D a t a / B D s
C0 0 C B F 1 9 2 B y t e s D u a l - P o r t R A M P a r a m e t e r R A M P a g e 1
D0 0 D B F 1 9 2 B y t e s D u a l - P o r t R A M P a r a m e t e r R A M P a g e 2
E0 0 E B F 1 9 2 B y t e s D u a l - P o r t R A M P a r a m e t e r R A M P a g e 3
F0 0 F B F 1 9 2 B y t e s D u a l - P o r t R A M P a r a m e t e r R A M P a g e 4
local i n t e r r u p t s l e v e l
NMI 7
PIT t i m e r , C P M ( R X / T X c o m p l e t e ) 4
PCI9 0 6 0 D M A a n d P C I d o o r b e l l s 3
Cable - n o t u s e d 1
* /
# include < l i n u x / h d l c . h >
2012-11-07 06:37:24 +04:00
# include < l i n u x / h d l c / i o c t l . h >
2005-04-17 02:20:36 +04:00
# include " w a n x l . h "
/* memory addresses and offsets */
MAX_ R A M _ S I Z E = 1 6 * 1 0 2 4 * 1 0 2 4 / / m a x R A M s u p p o r t e d b y h a r d w a r e
PCI9 0 6 0 _ V E C T O R = 0 x00 0 0 0 0 6 C
CPM_ I R Q _ B A S E = 0 x40
ERROR_ V E C T O R = C P M _ I R Q _ B A S E * 4
SCC1 _ V E C T O R = ( C P M _ I R Q _ B A S E + 0 x1 E ) * 4
SCC2 _ V E C T O R = ( C P M _ I R Q _ B A S E + 0 x1 D ) * 4
SCC3 _ V E C T O R = ( C P M _ I R Q _ B A S E + 0 x1 C ) * 4
SCC4 _ V E C T O R = ( C P M _ I R Q _ B A S E + 0 x1 B ) * 4
CPM_ I R Q _ L E V E L = 4
TIMER_ I R Q = 1 2 8
TIMER_ I R Q _ L E V E L = 4
PITR_ C O N S T = 0 x10 0 + 1 6 / / 1 H z t i m e r
MBAR = 0 x00 0 3 F F 0 0
VALUE_ W I N D O W = 0 x40 0 0 0 0 0 0
ORDER_ W I N D O W = 0 x C 0 0 0 0 0 0 0
PLX = 0 x F F F 9 0 0 0 0
CSRA = 0 x F F F B 0 0 0 0
CSRB = 0 x F F F B 0 0 0 2
CSRC = 0 x F F F B 0 0 0 4
CSRD = 0 x F F F B 0 0 0 6
STATUS_ C A B L E _ L L = 0 x20 0 0
STATUS_ C A B L E _ D T R = 0 x10 0 0
DPRBASE = 0 x F F F C 0 0 0 0
SCC1 _ B A S E = D P R B A S E + 0 x C 0 0
MISC_ B A S E = D P R B A S E + 0 x C B 0
SCC2 _ B A S E = D P R B A S E + 0 x D 0 0
SCC3 _ B A S E = D P R B A S E + 0 x E 0 0
SCC4 _ B A S E = D P R B A S E + 0 x F 0 0
/ / offset f r o m S C C x _ B A S E
/ / SCC_ x B A S E c o n t a i n o f f s e t s f r o m D P R B A S E a n d m u s t b e d i v i s i b l e b y 8
SCC_ R B A S E = 0 / / 1 6 - b i t R x B D b a s e a d d r e s s
SCC_ T B A S E = 2 / / 1 6 - b i t T x B D b a s e a d d r e s s
SCC_ R F C R = 4 / / 8 - b i t R x f u n c t i o n c o d e
SCC_ T F C R = 5 / / 8 - b i t T x f u n c t i o n c o d e
SCC_ M R B L R = 6 / / 1 6 - b i t m a x i m u m R x b u f f e r l e n g t h
SCC_ C _ M A S K = 0 x34 / / 3 2 - b i t C R C c o n s t a n t
SCC_ C _ P R E S = 0 x38 / / 3 2 - b i t C R C p r e s e t
SCC_ M F L R = 0 x46 / / 1 6 - b i t m a x R x f r a m e l e n g t h ( w i t h o u t f l a g s )
REGBASE = D P R B A S E + 0 x10 0 0
PICR = R E G B A S E + 0 x02 6 / / 1 6 - b i t p e r i o d i c i r q c o n t r o l
PITR = R E G B A S E + 0 x02 A / / 1 6 - b i t p e r i o d i c i r q t i m i n g
OR1 = R E G B A S E + 0 x06 4 / / 3 2 - b i t R A M b a n k #1 o p t i o n s
CICR = R E G B A S E + 0 x54 0 / / 3 2 ( 2 4 ) - b i t C P i n t e r r u p t c o n f i g
CIMR = R E G B A S E + 0 x54 8 / / 3 2 - b i t C P i n t e r r u p t m a s k
CISR = R E G B A S E + 0 x54 C / / 3 2 - b i t C P i n t e r r u p t s i n - s e r v i c e
PADIR = R E G B A S E + 0 x55 0 / / 1 6 - b i t P o r t A d a t a d i r e c t i o n b i t m a p
PAPAR = R E G B A S E + 0 x55 2 / / 1 6 - b i t P o r t A p i n a s s i g n m e n t b i t m a p
PAODR = R E G B A S E + 0 x55 4 / / 1 6 - b i t P o r t A o p e n d r a i n b i t m a p
PADAT = R E G B A S E + 0 x55 6 / / 1 6 - b i t P o r t A d a t a r e g i s t e r
PCDIR = R E G B A S E + 0 x56 0 / / 1 6 - b i t P o r t C d a t a d i r e c t i o n b i t m a p
PCPAR = R E G B A S E + 0 x56 2 / / 1 6 - b i t P o r t C p i n a s s i g n m e n t b i t m a p
PCSO = R E G B A S E + 0 x56 4 / / 1 6 - b i t P o r t C s p e c i a l o p t i o n s
PCDAT = R E G B A S E + 0 x56 6 / / 1 6 - b i t P o r t C d a t a r e g i s t e r
PCINT = R E G B A S E + 0 x56 8 / / 1 6 - b i t P o r t C i n t e r r u p t c o n t r o l
CR = R E G B A S E + 0 x5 C 0 / / 1 6 - b i t C o m m a n d r e g i s t e r
SCC1 _ R E G S = R E G B A S E + 0 x60 0
SCC2 _ R E G S = R E G B A S E + 0 x62 0
SCC3 _ R E G S = R E G B A S E + 0 x64 0
SCC4 _ R E G S = R E G B A S E + 0 x66 0
SICR = R E G B A S E + 0 x6 E C / / 3 2 - b i t S I c l o c k r o u t e
/ / offset f r o m S C C x _ R E G S
SCC_ G S M R _ L = 0 x00 / / 3 2 b i t s
SCC_ G S M R _ H = 0 x04 / / 3 2 b i t s
SCC_ P S M R = 0 x08 / / 1 6 b i t s
SCC_ T O D R = 0 x0 C / / 1 6 b i t s
SCC_ D S R = 0 x0 E / / 1 6 b i t s
SCC_ S C C E = 0 x10 / / 1 6 b i t s
SCC_ S C C M = 0 x14 / / 1 6 b i t s
SCC_ S C C S = 0 x17 / / 8 b i t s
# if Q U I C C _ M E M C P Y _ U S E S _ P L X
.macro memcpy_from_pci src, d e s t , l e n / / l e n m u s t b e < 8 M B
addl #3 , \ l e n
andl #0xFFFFFFFC , \ l e n / / a l w a y s c o p y n * 4 b y t e s
movel \ s r c , P L X _ D M A _ 0 _ P C I
movel \ d e s t , P L X _ D M A _ 0 _ L O C A L
movel \ l e n , P L X _ D M A _ 0 _ L E N G T H
movel #0x0103 , P L X _ D M A _ C M D _ S T S / / s t a r t c h a n n e l 0 t r a n s f e r
bsr m e m c p y _ f r o m _ p c i _ r u n
.endm
.macro memcpy_to_pci src, d e s t , l e n
addl #3 , \ l e n
andl #0xFFFFFFFC , \ l e n / / a l w a y s c o p y n * 4 b y t e s
movel \ s r c , P L X _ D M A _ 1 _ L O C A L
movel \ d e s t , P L X _ D M A _ 1 _ P C I
movel \ l e n , P L X _ D M A _ 1 _ L E N G T H
movel #0x0301 , P L X _ D M A _ C M D _ S T S / / s t a r t c h a n n e l 1 t r a n s f e r
bsr m e m c p y _ t o _ p c i _ r u n
.endm
# else
.macro memcpy src, d e s t , l e n / / l e n m u s t b e < 6 5 5 3 6 b y t e s
movel % d7 , - ( % s p ) / / s r c a n d d e s t m u s t b e < 2 5 6 M B
movel \ l e n , % d7 / / b i t s 0 a n d 1
lsrl #2 , \ l e n
andl \ l e n , \ l e n
beq 9 9 f / / o n l y 0 - 3 b y t e s
subl #1 , \ l e n / / f o r d b f
98 : movel ( \ s r c ) + , ( \ d e s t ) +
dbfw \ l e n , 9 8 b
99 : movel % d7 , \ l e n
btstl #1 , \ l e n
beq 9 9 f
movew ( \ s r c ) + , ( \ d e s t ) +
99 : btstl #0 , \ l e n
beq 9 9 f
moveb ( \ s r c ) + , ( \ d e s t ) +
99 :
movel ( % s p ) + , % d7
.endm
.macro memcpy_from_pci src, d e s t , l e n
addl #V A L U E _ W I N D O W , \ s r c
memcpy \ s r c , \ d e s t , \ l e n
.endm
.macro memcpy_to_pci src, d e s t , l e n
addl #V A L U E _ W I N D O W , \ d e s t
memcpy \ s r c , \ d e s t , \ l e n
.endm
# endif
.macro wait_for_command
99 : btstl #0 , C R
bne 9 9 b
.endm
/****************************** card initialization *******************/
.text
.global _start
_start : bra i n i t
.org _start + 4
ch_status_addr : .long 0 , 0 , 0 , 0
rx_descs_addr : .long 0
init :
# if D E T E C T _ R A M
movel O R 1 , % d0
andl #0xF00007FF , % d0 / / m a s k A M x x b i t s
orl #0xFFFF800 & ~ ( M A X _ R A M _ S I Z E - 1 ) , % d0 / / u p d a t e R A M b a n k s i z e
movel % d0 , O R 1
# endif
addl #V A L U E _ W I N D O W , r x _ d e s c s _ a d d r / / P C I a d d r e s s e s o f s h a r e d d a t a
clrl % d0 / / D 0 = 4 * p o r t
init_1 : tstl c h _ s t a t u s _ a d d r ( % d0 )
beq i n i t _ 2
addl #V A L U E _ W I N D O W , c h _ s t a t u s _ a d d r ( % d 0 )
init_2 : addl #4 , % d0
cmpl #4 * 4 , % d0
bne i n i t _ 1
movel #p c i 9060 _ i n t e r r u p t , P C I 9 0 6 0 _ V E C T O R
movel #e r r o r _ i n t e r r u p t , E R R O R _ V E C T O R
movel #p o r t _ i n t e r r u p t _ 1 , S C C 1 _ V E C T O R
movel #p o r t _ i n t e r r u p t _ 2 , S C C 2 _ V E C T O R
movel #p o r t _ i n t e r r u p t _ 3 , S C C 3 _ V E C T O R
movel #p o r t _ i n t e r r u p t _ 4 , S C C 4 _ V E C T O R
movel #t i m e r _ i n t e r r u p t , T I M E R _ I R Q * 4
movel #0x78000000 , C I M R / / o n l y S C C x I R Q s f r o m C P M
movew #( T I M E R _ I R Q _ L E V E L < < 8 ) + T I M E R _ I R Q , P I C R / / i n t e r r u p t f r o m P I T
movew #P I T R _ C O N S T , P I T R
/ / SCC1 =SCCa S C C 2 =SCCb S C C 3 =SCCc S C C 4 =SCCd p r i o =4 H P = - 1 I R Q =64 - 7 9
movel #0xD41F40 + ( C P M _ I R Q _ L E V E L < < 1 3 ) , C I C R
movel #0x543 , P L X _ D M A _ 0 _ M O D E / / 3 2 - b i t , R e a d y , B u r s t , I R Q
movel #0x543 , P L X _ D M A _ 1 _ M O D E
movel #0x0 , P L X _ D M A _ 0 _ D E S C / / f r o m P C I t o l o c a l
movel #0x8 , P L X _ D M A _ 1 _ D E S C / / f r o m l o c a l t o P C I
movel #0x101 , P L X _ D M A _ C M D _ S T S / / e n a b l e b o t h D M A c h a n n e l s
/ / enable l o c a l I R Q , D M A , d o o r b e l l s a n d P C I I R Q
orl #0x000F0300 , P L X _ I N T E R R U P T _ C S
# if D E T E C T _ R A M
bsr r a m _ t e s t
# else
movel #1 , P L X _ M A I L B O X _ 5 / / n o n - z e r o v a l u e = i n i t c o m p l e t e
# endif
bsr c h e c k _ c s r
movew #0xFFFF , P A P A R / / a l l p i n s a r e c l o c k s / d a t a
clrw P A D I R / / f i r s t f u n c t i o n
clrw P C S O / / C D a n d C T S a l w a y s a c t i v e
/****************************** main loop *****************************/
main : movel c h a n n e l _ s t a t s , % d7 / / D 7 = d o o r b e l l + i r q s t a t u s
clrl c h a n n e l _ s t a t s
tstl % d7
bne m a i n _ 1
/ / nothing t o d o - w a i t f o r n e x t e v e n t
stop #0x2200 / / s u p e r v i s o r + I R Q l e v e l 2
movew #0x2700 , % s r / / d i s a b l e I R Q s a g a i n
bra m a i n
main_1 : clrl % d0 / / D 0 = 4 * p o r t
clrl % d6 / / D 6 = d o o r b e l l t o h o s t v a l u e
main_l : btstl #D O O R B E L L _ T O _ C A R D _ C L O S E _ 0 , % d7
beq m a i n _ o p
bclrl #D O O R B E L L _ T O _ C A R D _ O P E N _ 0 , % d7 / / i n c a s e b o t h b i t s a r e s e t
bsr c l o s e _ p o r t
main_op :
btstl #D O O R B E L L _ T O _ C A R D _ O P E N _ 0 , % d7
beq m a i n _ c l
bsr o p e n _ p o r t
main_cl :
btstl #D O O R B E L L _ T O _ C A R D _ T X _ 0 , % d7
beq m a i n _ t x e n d
bsr t x
main_txend :
btstl #T A S K _ S C C _ 0 , % d7
beq m a i n _ n e x t
bsr t x _ e n d
bsr r x
main_next :
lsrl #1 , % d7 / / p o r t s t a t u s f o r n e x t p o r t
addl #4 , % d0 / / D 0 = 4 * n e x t p o r t
cmpl #4 * 4 , % d0
bne m a i n _ l
movel % d6 , P L X _ D O O R B E L L _ F R O M _ C A R D / / s i g n a l t h e h o s t
bra m a i n
/****************************** open port *****************************/
open_port : / / D0 = 4 * p o r t , D 6 = d o o r b e l l t o h o s t
movel c h _ s t a t u s _ a d d r ( % d0 ) , % a0 / / A 0 = p o r t s t a t u s a d d r e s s
tstl S T A T U S _ O P E N ( % a0 )
bne o p e n _ p o r t _ r e t / / p o r t a l r e a d y o p e n
movel #1 , S T A T U S _ O P E N ( % a0 ) / / c o n f i r m t h e p o r t i s o p e n
/ / setup B D s
clrl t x _ i n ( % d0 )
clrl t x _ o u t ( % d0 )
clrl t x _ c o u n t ( % d0 )
clrl r x _ i n ( % d0 )
movel S I C R , % d1 / / D 1 = c l o c k s e t t i n g s i n S I C R
andl c l o c k i n g _ m a s k ( % d0 ) , % d1
cmpl #C L O C K _ T X F R O M R X , S T A T U S _ C L O C K I N G ( % a 0 )
bne o p e n _ p o r t _ c l o c k _ e x t
orl c l o c k i n g _ t x f r o m r x ( % d0 ) , % d1
bra o p e n _ p o r t _ s e t _ c l o c k
open_port_clock_ext :
orl c l o c k i n g _ e x t ( % d0 ) , % d1
open_port_set_clock :
movel % d1 , S I C R / / u p d a t e c l o c k s e t t i n g s i n S I C R
orw #S T A T U S _ C A B L E _ D T R , c s r _ o u t p u t ( % d 0 ) / / D T R o n
bsr c h e c k _ c s r / / c a l l w i t h d i s a b l e d t i m e r i n t e r r u p t
/ / Setup T X d e s c r i p t o r s
movel f i r s t _ b u f f e r ( % d0 ) , % d1 / / D 1 = s t a r t i n g b u f f e r a d d r e s s
movel t x _ f i r s t _ b d ( % d0 ) , % a1 / / A 1 = s t a r t i n g T X B D a d d r e s s
movel #T X _ B U F F E R S - 2 , % d2 / / D 2 = T X _ B U F F E R S - 1 c o u n t e r
movel #0x18000000 , % d3 / / D 3 = i n i t i a l T X B D f l a g s : I n t + L a s t
cmpl #P A R I T Y _ N O N E , S T A T U S _ P A R I T Y ( % a 0 )
beq o p e n _ p o r t _ t x _ l o o p
bsetl #26 , % d3 / / T X B D f l a g : T r a n s m i t C R C
open_port_tx_loop :
movel % d3 , ( % a1 ) + / / T X f l a g s + l e n g t h
movel % d1 , ( % a1 ) + / / b u f f e r a d d r e s s
addl #B U F F E R _ L E N G T H , % d 1
dbfw % d2 , o p e n _ p o r t _ t x _ l o o p
bsetl #29 , % d3 / / T X B D f l a g : W r a p ( l a s t B D )
movel % d3 , ( % a1 ) + / / F i n a l T X f l a g s + l e n g t h
movel % d1 , ( % a1 ) + / / b u f f e r a d d r e s s
/ / Setup R X d e s c r i p t o r s / / A 1 = s t a r t i n g R X B D a d d r e s s
movel #R X _ B U F F E R S - 2 , % d2 / / D 2 = R X _ B U F F E R S - 1 c o u n t e r
open_port_rx_loop :
movel #0x90000000 , ( % a1 ) + / / R X f l a g s + l e n g t h
movel % d1 , ( % a1 ) + / / b u f f e r a d d r e s s
addl #B U F F E R _ L E N G T H , % d 1
dbfw % d2 , o p e n _ p o r t _ r x _ l o o p
movel #0xB0000000 , ( % a1 ) + / / F i n a l R X f l a g s + l e n g t h
movel % d1 , ( % a1 ) + / / b u f f e r a d d r e s s
/ / Setup p o r t p a r a m e t e r s
movel s c c _ b a s e _ a d d r ( % d0 ) , % a1 / / A 1 = S C C _ B A S E a d d r e s s
movel s c c _ r e g _ a d d r ( % d0 ) , % a2 / / A 2 = S C C _ R E G S a d d r e s s
movel #0xFFFF , S C C _ S C C E ( % a2 ) / / c l e a r s t a t u s b i t s
movel #0x0000 , S C C _ S C C M ( % a2 ) / / i n t e r r u p t m a s k
movel t x _ f i r s t _ b d ( % d0 ) , % d1
movew % d1 , S C C _ T B A S E ( % a1 ) / / D 1 = o f f s e t o f f i r s t T x B D
addl #T X _ B U F F E R S * 8 , % d1
movew % d1 , S C C _ R B A S E ( % a1 ) / / D 1 = o f f s e t o f f i r s t R x B D
moveb #0x8 , S C C _ R F C R ( % a1 ) / / I n t e l m o d e , 1 0 0 0
moveb #0x8 , S C C _ T F C R ( % a1 )
/ / Parity s e t t i n g s
cmpl #P A R I T Y _ C R C 16 _ P R 1 _ C C I T T , S T A T U S _ P A R I T Y ( % a0 )
bne o p e n _ p o r t _ p a r i t y _ 1
clrw S C C _ P S M R ( % a2 ) / / C R C 1 6 - C C I T T
movel #0xF0B8 , S C C _ C _ M A S K ( % a1 )
movel #0xFFFF , S C C _ C _ P R E S ( % a1 )
movew #H D L C _ M A X _ M R U + 2 , S C C _ M F L R ( % a1 ) / / 2 b y t e s f o r C R C
movew #2 , p a r i t y _ b y t e s ( % d0 )
bra o p e n _ p o r t _ 2
open_port_parity_1 :
cmpl #P A R I T Y _ C R C 32 _ P R 1 _ C C I T T , S T A T U S _ P A R I T Y ( % a0 )
bne o p e n _ p o r t _ p a r i t y _ 2
movew #0x0800 , S C C _ P S M R ( % a2 ) / / C R C 3 2 - C C I T T
movel #0xDEBB20E3 , S C C _ C _ M A S K ( % a1 )
movel #0xFFFFFFFF , S C C _ C _ P R E S ( % a1 )
movew #H D L C _ M A X _ M R U + 4 , S C C _ M F L R ( % a1 ) / / 4 b y t e s f o r C R C
movew #4 , p a r i t y _ b y t e s ( % d0 )
bra o p e n _ p o r t _ 2
open_port_parity_2 :
cmpl #P A R I T Y _ C R C 16 _ P R 0 _ C C I T T , S T A T U S _ P A R I T Y ( % a0 )
bne o p e n _ p o r t _ p a r i t y _ 3
clrw S C C _ P S M R ( % a2 ) / / C R C 1 6 - C C I T T p r e s e t 0
movel #0xF0B8 , S C C _ C _ M A S K ( % a1 )
clrl S C C _ C _ P R E S ( % a1 )
movew #H D L C _ M A X _ M R U + 2 , S C C _ M F L R ( % a1 ) / / 2 b y t e s f o r C R C
movew #2 , p a r i t y _ b y t e s ( % d0 )
bra o p e n _ p o r t _ 2
open_port_parity_3 :
cmpl #P A R I T Y _ C R C 32 _ P R 0 _ C C I T T , S T A T U S _ P A R I T Y ( % a0 )
bne o p e n _ p o r t _ p a r i t y _ 4
movew #0x0800 , S C C _ P S M R ( % a2 ) / / C R C 3 2 - C C I T T p r e s e t 0
movel #0xDEBB20E3 , S C C _ C _ M A S K ( % a1 )
clrl S C C _ C _ P R E S ( % a1 )
movew #H D L C _ M A X _ M R U + 4 , S C C _ M F L R ( % a1 ) / / 4 b y t e s f o r C R C
movew #4 , p a r i t y _ b y t e s ( % d0 )
bra o p e n _ p o r t _ 2
open_port_parity_4 :
clrw S C C _ P S M R ( % a2 ) / / n o p a r i t y
movel #0xF0B8 , S C C _ C _ M A S K ( % a1 )
movel #0xFFFF , S C C _ C _ P R E S ( % a1 )
movew #H D L C _ M A X _ M R U , S C C _ M F L R ( % a 1 ) / / 0 b y t e s f o r C R C
clrw p a r i t y _ b y t e s ( % d0 )
open_port_2 :
movel #0x00000003 , S C C _ G S M R _ H ( % a2 ) / / R T S M
cmpl #E N C O D I N G _ N R Z I , S T A T U S _ E N C O D I N G ( % a 0 )
bne o p e n _ p o r t _ n r z
movel #0x10040900 , S C C _ G S M R _ L ( % a2 ) / / N R Z I : T C I T e n d R E C N + T E N C =1
bra o p e n _ p o r t _ 3
open_port_nrz :
movel #0x10040000 , S C C _ G S M R _ L ( % a2 ) / / N R Z : T C I T e n d R E C N + T E N C =0
open_port_3 :
movew #B U F F E R _ L E N G T H , S C C _ M R B L R ( % a 1 )
movel % d0 , % d1
lsll #4 , % d1 / / D 1 b i t s 7 a n d 6 = p o r t
orl #1 , % d1
movew % d1 , C R / / I n i t S C C R X a n d T X p a r a m s
wait_ f o r _ c o m m a n d
/ / TCI T e n d E N R E N T
movew #0x001F , S C C _ S C C M ( % a2 ) / / T X E R X F B S Y T X B R X B i n t e r r u p t s
orl #0x00000030 , S C C _ G S M R _ L ( % a2 ) / / e n a b l e S C C
open_port_ret :
rts
/****************************** close port ****************************/
close_port : / / D0 = 4 * p o r t , D 6 = d o o r b e l l t o h o s t
movel s c c _ r e g _ a d d r ( % d0 ) , % a0 / / A 0 = S C C _ R E G S a d d r e s s
clrw S C C _ S C C M ( % a0 ) / / n o S C C i n t e r r u p t s
andl #0xFFFFFFCF , S C C _ G S M R _ L ( % a0 ) / / D i s a b l e E N T a n d E N R
andw #~ S T A T U S _ C A B L E _ D T R , c s r _ o u t p u t ( % d 0 ) / / D T R o f f
bsr c h e c k _ c s r / / c a l l w i t h d i s a b l e d t i m e r i n t e r r u p t
movel c h _ s t a t u s _ a d d r ( % d0 ) , % d1
clrl S T A T U S _ O P E N ( % d1 ) / / c o n f i r m t h e p o r t i s c l o s e d
rts
/****************************** transmit packet ***********************/
/ / queue p a c k e t s f o r t r a n s m i s s i o n
tx : / / D0 = 4 * p o r t , D 6 = d o o r b e l l t o h o s t
cmpl #T X _ B U F F E R S , t x _ c o u n t ( % d 0 )
beq t x _ r e t / / a l l D B ' s = d e s c s i n u s e
movel t x _ o u t ( % d0 ) , % d1
movel % d1 , % d2 / / D 1 = D 2 = t x _ o u t B D # = d e s c #
mulul #D E S C _ L E N G T H , % d 2 / / D 2 = T X d e s c o f f s e t
addl c h _ s t a t u s _ a d d r ( % d0 ) , % d2
addl #S T A T U S _ T X _ D E S C S , % d 2 / / D 2 = T X d e s c a d d r e s s
cmpl #P A C K E T _ F U L L , ( % d 2 ) / / d e s c s t a t u s
bne t x _ r e t
/ / queue i t
movel 4 ( % d2 ) , % a0 / / P C I a d d r e s s
lsll #3 , % d1 / / B D i s 8 - b y t e s l o n g
addl t x _ f i r s t _ b d ( % d0 ) , % d1 / / D 1 = c u r r e n t t x _ o u t B D a d d r
movel 4 ( % d1 ) , % a1 / / A 1 = d e s t a d d r e s s
movel 8 ( % d2 ) , % d2 / / D 2 = l e n g t h
movew % d2 , 2 ( % d1 ) / / l e n g t h i n t o B D
memcpy_ f r o m _ p c i % a0 , % a1 , % d2
bsetl #31 , ( % d1 ) / / C P g o a h e a d
/ / update t x _ o u t a n d t x _ c o u n t
movel t x _ o u t ( % d0 ) , % d1
addl #1 , % d1
cmpl #T X _ B U F F E R S , % d 1
bne t x _ 1
clrl % d1
tx_1 : movel % d1 , t x _ o u t ( % d0 )
addl #1 , t x _ c o u n t ( % d0 )
bra t x
tx_ret : rts
/****************************** packet received ***********************/
/ / Service r e c e i v e b u f f e r s / / D 0 = 4 * p o r t , D 6 = d o o r b e l l t o h o s t
rx : movel r x _ i n ( % d0 ) , % d1 / / D 1 = r x _ i n B D #
lsll #3 , % d1 / / B D i s 8 - b y t e s l o n g
addl r x _ f i r s t _ b d ( % d0 ) , % d1 / / D 1 = c u r r e n t r x _ i n B D a d d r e s s
movew ( % d1 ) , % d2 / / D 2 = R X B D f l a g s
btstl #15 , % d2
bne r x _ r e t / / B D s t i l l e m p t y
btstl #1 , % d2
bne r x _ o v e r r u n
tstw p a r i t y _ b y t e s ( % d0 )
bne r x _ p a r i t y
bclrl #2 , % d2 / / d o n o t t e s t f o r C R C e r r o r s
rx_parity :
andw #0x0CBC , % d2 / / m a s k s t a t u s b i t s
cmpw #0x0C00 , % d2 / / c o r r e c t f r a m e
bne r x _ b a d _ f r a m e
clrl % d3
movew 2 ( % d1 ) , % d3
subw p a r i t y _ b y t e s ( % d0 ) , % d3 / / D 3 = p a c k e t l e n g t h
cmpw #H D L C _ M A X _ M R U , % d 3
bgt r x _ b a d _ f r a m e
rx_good_frame :
movel r x _ o u t , % d2
mulul #D E S C _ L E N G T H , % d 2
addl r x _ d e s c s _ a d d r , % d2 / / D 2 = R X d e s c a d d r e s s
cmpl #P A C K E T _ E M P T Y , ( % d 2 ) / / d e s c s t a t
bne r x _ o v e r r u n
movel % d3 , 8 ( % d2 )
movel 4 ( % d1 ) , % a0 / / A 0 = s o u r c e a d d r e s s
movel 4 ( % d2 ) , % a1
tstl % a1
beq r x _ i g n o r e _ d a t a
memcpy_ t o _ p c i % a0 , % a1 , % d3
rx_ignore_data :
movel p a c k e t _ f u l l ( % d0 ) , ( % d2 ) / / u p d a t e d e s c s t a t
/ / update D 6 a n d r x _ o u t
bsetl #D O O R B E L L _ F R O M _ C A R D _ R X , % d 6 / / s i g n a l h o s t t h a t R X c o m p l e t e d
movel r x _ o u t , % d2
addl #1 , % d2
cmpl #R X _ Q U E U E _ L E N G T H , % d 2
bne r x _ 1
clrl % d2
rx_1 : movel % d2 , r x _ o u t
rx_free_bd :
andw #0xF000 , ( % d1 ) / / c l e a r C M a n d e r r o r b i t s
bsetl #31 , ( % d1 ) / / f r e e B D
/ / update r x _ i n
movel r x _ i n ( % d0 ) , % d1
addl #1 , % d1
cmpl #R X _ B U F F E R S , % d 1
bne r x _ 2
clrl % d1
rx_2 : movel % d1 , r x _ i n ( % d0 )
bra r x
rx_overrun :
movel c h _ s t a t u s _ a d d r ( % d0 ) , % d2
addl #1 , S T A T U S _ R X _ O V E R R U N S ( % d2 )
bra r x _ f r e e _ b d
rx_bad_frame :
movel c h _ s t a t u s _ a d d r ( % d0 ) , % d2
addl #1 , S T A T U S _ R X _ F R A M E _ E R R O R S ( % d2 )
bra r x _ f r e e _ b d
rx_ret : rts
/****************************** packet transmitted ********************/
/ / Service t r a n s m i t b u f f e r s / / D 0 = 4 * p o r t , D 6 = d o o r b e l l t o h o s t
tx_end : tstl t x _ c o u n t ( % d0 )
beq t x _ e n d _ r e t / / T X b u f f e r s a l r e a d y e m p t y
movel t x _ i n ( % d0 ) , % d1
movel % d1 , % d2 / / D 1 = D 2 = t x _ i n B D # = d e s c #
lsll #3 , % d1 / / B D i s 8 - b y t e s l o n g
addl t x _ f i r s t _ b d ( % d0 ) , % d1 / / D 1 = c u r r e n t t x _ i n B D a d d r e s s
movew ( % d1 ) , % d3 / / D 3 = T X B D f l a g s
btstl #15 , % d3
bne t x _ e n d _ r e t / / B D s t i l l b e i n g t r a n s m i t t e d
/ / update D 6 , t x _ i n a n d t x _ c o u n t
orl b e l l _ t x ( % d0 ) , % d6 / / s i g n a l h o s t t h a t T X d e s c f r e e d
subl #1 , t x _ c o u n t ( % d0 )
movel t x _ i n ( % d0 ) , % d1
addl #1 , % d1
cmpl #T X _ B U F F E R S , % d 1
bne t x _ e n d _ 1
clrl % d1
tx_end_1 :
movel % d1 , t x _ i n ( % d0 )
/ / free h o s t ' s d e s c r i p t o r
mulul #D E S C _ L E N G T H , % d 2 / / D 2 = T X d e s c o f f s e t
addl c h _ s t a t u s _ a d d r ( % d0 ) , % d2
addl #S T A T U S _ T X _ D E S C S , % d 2 / / D 2 = T X d e s c a d d r e s s
btstl #1 , % d3
bne t x _ e n d _ u n d e r r u n
movel #P A C K E T _ S E N T , ( % d 2 )
bra t x _ e n d
tx_end_underrun :
movel #P A C K E T _ U N D E R R U N , ( % d 2 )
bra t x _ e n d
tx_end_ret : rts
/****************************** PLX PCI9060 DMA memcpy ****************/
# if Q U I C C _ M E M C P Y _ U S E S _ P L X
/ / called w i t h i n t e r r u p t s d i s a b l e d
memcpy_from_pci_run :
movel % d0 , - ( % s p )
movew % s r , - ( % s p )
memcpy_1 :
movel P L X _ D M A _ C M D _ S T S , % d0 / / d o n o t b t s t P L X r e g i s t e r d i r e c t l y
btstl #4 , % d0 / / t r a n s f e r d o n e ?
bne m e m c p y _ e n d
stop #0x2200 / / e n a b l e P C I 9 0 6 0 i n t e r r u p t s
movew #0x2700 , % s r / / d i s a b l e i n t e r r u p t s a g a i n
bra m e m c p y _ 1
memcpy_to_pci_run :
movel % d0 , - ( % s p )
movew % s r , - ( % s p )
memcpy_2 :
movel P L X _ D M A _ C M D _ S T S , % d0 / / d o n o t b t s t P L X r e g i s t e r d i r e c t l y
btstl #12 , % d0 / / t r a n s f e r d o n e ?
bne m e m c p y _ e n d
stop #0x2200 / / e n a b l e P C I 9 0 6 0 i n t e r r u p t s
movew #0x2700 , % s r / / d i s a b l e i n t e r r u p t s a g a i n
bra m e m c p y _ 2
memcpy_end :
movew ( % s p ) + , % s r
movel ( % s p ) + , % d0
rts
# endif
/****************************** PLX PCI9060 interrupt *****************/
pci9060_interrupt :
movel % d0 , - ( % s p )
movel P L X _ D O O R B E L L _ T O _ C A R D , % d0
movel % d0 , P L X _ D O O R B E L L _ T O _ C A R D / / c o n f i r m a l l r e q u e s t s
orl % d0 , c h a n n e l _ s t a t s
movel #0x0909 , P L X _ D M A _ C M D _ S T S / / c l e a r D M A c h #0 a n d #1 i n t e r r u p t s
movel ( % s p ) + , % d0
rte
/****************************** SCC interrupts ************************/
port_interrupt_1 :
orl #0 , S C C 1 _ R E G S + S C C _ S C C E ; // confirm SCC events
orl #1 < < T A S K _ S C C _ 0 , c h a n n e l _ s t a t s
movel #0x40000000 , C I S R
rte
port_interrupt_2 :
orl #0 , S C C 2 _ R E G S + S C C _ S C C E ; // confirm SCC events
orl #1 < < T A S K _ S C C _ 1 , c h a n n e l _ s t a t s
movel #0x20000000 , C I S R
rte
port_interrupt_3 :
orl #0 , S C C 3 _ R E G S + S C C _ S C C E ; // confirm SCC events
orl #1 < < T A S K _ S C C _ 2 , c h a n n e l _ s t a t s
movel #0x10000000 , C I S R
rte
port_interrupt_4 :
orl #0 , S C C 4 _ R E G S + S C C _ S C C E ; // confirm SCC events
orl #1 < < T A S K _ S C C _ 3 , c h a n n e l _ s t a t s
movel #0x08000000 , C I S R
rte
error_interrupt :
rte
/****************************** cable and PM routine ******************/
/ / modified r e g i s t e r s : n o n e
check_csr :
movel % d0 , - ( % s p )
movel % d1 , - ( % s p )
movel % d2 , - ( % s p )
movel % a0 , - ( % s p )
movel % a1 , - ( % s p )
clrl % d0 / / D 0 = 4 * p o r t
movel #C S R A , % a 0 / / A 0 = C S R a d d r e s s
check_csr_loop :
movew ( % a0 ) , % d1 / / D 1 = C S R i n p u t b i t s
andl #0xE7 , % d1 / / P M a n d c a b l e s e n s e b i t s ( n o D C E b i t )
cmpw #S T A T U S _ C A B L E _ V 35 * ( 1 + 1 < < S T A T U S _ C A B L E _ P M _ S H I F T ) , % d1
bne c h e c k _ c s r _ 1
movew #0x0E08 , % d1
bra c h e c k _ c s r _ v a l i d
check_csr_1 :
cmpw #S T A T U S _ C A B L E _ X 21 * ( 1 + 1 < < S T A T U S _ C A B L E _ P M _ S H I F T ) , % d1
bne c h e c k _ c s r _ 2
movew #0x0408 , % d1
bra c h e c k _ c s r _ v a l i d
check_csr_2 :
cmpw #S T A T U S _ C A B L E _ V 24 * ( 1 + 1 < < S T A T U S _ C A B L E _ P M _ S H I F T ) , % d1
bne c h e c k _ c s r _ 3
movew #0x0208 , % d1
bra c h e c k _ c s r _ v a l i d
check_csr_3 :
cmpw #S T A T U S _ C A B L E _ E I A 530 * ( 1 + 1 < < S T A T U S _ C A B L E _ P M _ S H I F T ) , % d1
bne c h e c k _ c s r _ d i s a b l e
movew #0x0D08 , % d1
bra c h e c k _ c s r _ v a l i d
check_csr_disable :
movew #0x0008 , % d1 / / D 1 = d i s a b l e e v e r y t h i n g
movew #0x80E7 , % d2 / / D 2 = i n p u t m a s k : i g n o r e D S R
bra c h e c k _ c s r _ w r i t e
check_csr_valid : / / D1 = m o d e a n d I R Q b i t s
movew c s r _ o u t p u t ( % d0 ) , % d2
andw #0x3000 , % d2 / / D 2 = r e q u e s t e d L L a n d D T R b i t s
orw % d2 , % d1 / / D 1 = a l l r e q u e s t e d o u t p u t b i t s
movew #0x80FF , % d2 / / D 2 = i n p u t m a s k : i n c l u d e D S R
check_csr_write :
cmpw o l d _ c s r _ o u t p u t ( % d0 ) , % d1
beq c h e c k _ c s r _ i n p u t
movew % d1 , o l d _ c s r _ o u t p u t ( % d0 )
movew % d1 , ( % a0 ) / / W r i t e C S R o u t p u t b i t s
check_csr_input :
movew ( P C D A T ) , % d1
andw d c d _ m a s k ( % d0 ) , % d1
beq c h e c k _ c s r _ d c d _ o n / / D C D a n d C T S s i g n a l s a r e n e g a t e d
movew ( % a0 ) , % d1 / / D 1 = C S R i n p u t b i t s
andw #~ S T A T U S _ C A B L E _ D C D , % d 1 / / D C D o f f
bra c h e c k _ c s r _ p r e v i o u s
check_csr_dcd_on :
movew ( % a0 ) , % d1 / / D 1 = C S R i n p u t b i t s
orw #S T A T U S _ C A B L E _ D C D , % d 1 / / D C D o n
check_csr_previous :
andw % d2 , % d1 / / i n p u t m a s k
movel c h _ s t a t u s _ a d d r ( % d0 ) , % a1
cmpl S T A T U S _ C A B L E ( % a1 ) , % d1 / / c h e c k f o r c h a n g e
beq c h e c k _ c s r _ n e x t
movel % d1 , S T A T U S _ C A B L E ( % a1 ) / / u p d a t e s t a t u s
movel b e l l _ c a b l e ( % d0 ) , P L X _ D O O R B E L L _ F R O M _ C A R D / / s i g n a l t h e h o s t
check_csr_next :
addl #2 , % a0 / / n e x t C S R r e g i s t e r
addl #4 , % d0 / / D 0 = 4 * n e x t p o r t
cmpl #4 * 4 , % d0
bne c h e c k _ c s r _ l o o p
movel ( % s p ) + , % a1
movel ( % s p ) + , % a0
movel ( % s p ) + , % d2
movel ( % s p ) + , % d1
movel ( % s p ) + , % d0
rts
/****************************** timer interrupt ***********************/
timer_interrupt :
bsr c h e c k _ c s r
rte
/****************************** RAM sizing and test *******************/
# if D E T E C T _ R A M
ram_test :
movel #0x12345678 , % d1 / / D 1 = t e s t v a l u e
movel % d1 , ( 1 2 8 * 1 0 2 4 - 4 )
movel #128 * 1 0 2 4 , % d0 / / D 0 = R A M s i z e t e s t e d
ram_test_size :
cmpl #M A X _ R A M _ S I Z E , % d 0
beq r a m _ t e s t _ s i z e _ f o u n d
movel % d0 , % a0
addl #128 * 1 0 2 4 - 4 , % a0
cmpl ( % a0 ) , % d1
beq r a m _ t e s t _ s i z e _ c h e c k
ram_test_next_size :
lsll #1 , % d0
bra r a m _ t e s t _ s i z e
ram_test_size_check :
eorl #0xFFFFFFFF , % d1
movel % d1 , ( 1 2 8 * 1 0 2 4 - 4 )
cmpl ( % a0 ) , % d1
bne r a m _ t e s t _ n e x t _ s i z e
ram_test_size_found : / / D0 = R A M s i z e
movel % d0 , % a0 / / A 0 = f i l l p t r
subl #f i r m w a r e _ e n d + 4 , % d0
lsrl #2 , % d0
movel % d0 , % d1 / / D 1 = D B f c o u n t e r
ram_test_fill :
movel % a0 , - ( % a0 )
dbfw % d1 , r a m _ t e s t _ f i l l
subl #0x10000 , % d1
cmpl #0xFFFFFFFF , % d1
bne r a m _ t e s t _ f i l l
ram_test_loop : / / D0 = D B f c o u n t e r
cmpl ( % a0 ) + , % a0
dbnew % d0 , r a m _ t e s t _ l o o p
bne r a m _ t e s t _ f o u n d _ b a d
subl #0x10000 , % d0
cmpl #0xFFFFFFFF , % d0
bne r a m _ t e s t _ l o o p
bra r a m _ t e s t _ a l l _ o k
ram_test_found_bad :
subl #4 , % a0
ram_test_all_ok :
movel % a0 , P L X _ M A I L B O X _ 5
rts
# endif
/****************************** constants *****************************/
scc_reg_addr :
.long SCC1 _ R E G S , S C C 2 _ R E G S , S C C 3 _ R E G S , S C C 4 _ R E G S
scc_base_addr :
.long SCC1 _ B A S E , S C C 2 _ B A S E , S C C 3 _ B A S E , S C C 4 _ B A S E
tx_first_bd :
.long DPRBASE
.long DPRBASE + ( TX_ B U F F E R S + R X _ B U F F E R S ) * 8
.long DPRBASE + ( TX_ B U F F E R S + R X _ B U F F E R S ) * 8 * 2
.long DPRBASE + ( TX_ B U F F E R S + R X _ B U F F E R S ) * 8 * 3
rx_first_bd :
.long DPRBASE + TX_ B U F F E R S * 8
.long DPRBASE + TX_ B U F F E R S * 8 + ( T X _ B U F F E R S + R X _ B U F F E R S ) * 8
.long DPRBASE + TX_ B U F F E R S * 8 + ( T X _ B U F F E R S + R X _ B U F F E R S ) * 8 * 2
.long DPRBASE + TX_ B U F F E R S * 8 + ( T X _ B U F F E R S + R X _ B U F F E R S ) * 8 * 3
first_buffer :
.long BUFFERS_ADDR
.long BUFFERS_ADDR + ( TX_ B U F F E R S + R X _ B U F F E R S ) * B U F F E R _ L E N G T H
.long BUFFERS_ADDR + ( TX_ B U F F E R S + R X _ B U F F E R S ) * B U F F E R _ L E N G T H * 2
.long BUFFERS_ADDR + ( TX_ B U F F E R S + R X _ B U F F E R S ) * B U F F E R _ L E N G T H * 3
bell_tx :
.long 1 < < DOORBELL_ F R O M _ C A R D _ T X _ 0 , 1 < < D O O R B E L L _ F R O M _ C A R D _ T X _ 1
.long 1 < < DOORBELL_ F R O M _ C A R D _ T X _ 2 , 1 < < D O O R B E L L _ F R O M _ C A R D _ T X _ 3
bell_cable :
.long 1 < < DOORBELL_ F R O M _ C A R D _ C A B L E _ 0 , 1 < < D O O R B E L L _ F R O M _ C A R D _ C A B L E _ 1
.long 1 < < DOORBELL_ F R O M _ C A R D _ C A B L E _ 2 , 1 < < D O O R B E L L _ F R O M _ C A R D _ C A B L E _ 3
packet_full :
.long PACKET_ F U L L , P A C K E T _ F U L L + 1 , P A C K E T _ F U L L + 2 , P A C K E T _ F U L L + 3
clocking_ext :
.long 0 x0 0 0 0 0 0 2 C , 0 x00 0 0 3 E 0 0 , 0 x00 2 C 0 0 0 0 , 0 x3 E 0 0 0 0 0 0
clocking_txfromrx :
.long 0 x0 0 0 0 0 0 2 D , 0 x00 0 0 3 F 0 0 , 0 x00 2 D 0 0 0 0 , 0 x3 F 0 0 0 0 0 0
clocking_mask :
.long 0 x0 0 0 0 0 0 F F , 0 x00 0 0 F F 0 0 , 0 x00 F F 0 0 0 0 , 0 x F F 0 0 0 0 0 0
dcd_mask :
.word 0 x0 2 0 , 0 , 0 x08 0 , 0 , 0 x20 0 , 0 , 0 x80 0
.ascii " wanXL f i r m w a r e \ n "
.asciz " Copyright ( C ) 2 0 0 3 K r z y s z t o f H a l a s a < k h c @pm.waw.pl>\n"
/****************************** variables *****************************/
.align 4
channel_stats : .long 0
tx_in : .long 0 , 0 , 0 , 0 / / transmitted
tx_out : .long 0 , 0 , 0 , 0 / / received f r o m h o s t f o r t r a n s m i s s i o n
tx_count : .long 0 , 0 , 0 , 0 / / currently i n t r a n s m i t q u e u e
rx_in : .long 0 , 0 , 0 , 0 / / received f r o m p o r t
rx_out : .long 0 / / transmitted t o h o s t
parity_bytes : .word 0 , 0 , 0 , 0 , 0 , 0 , 0 / / only 4 w o r d s a r e u s e d
csr_output : .word 0
old_csr_output : .word 0 , 0 , 0 , 0 , 0 , 0 , 0
.align 4
firmware_end : / / must b e d w o r d - a l i g n e d