Merge branch 'master'
[linux-2.6] / drivers / net / sk98lin / skgehwt.c
1 /******************************************************************************
2  *
3  * Name:        skgehwt.c
4  * Project:     Gigabit Ethernet Adapters, Event Scheduler Module
5  * Version:     $Revision: 1.15 $
6  * Date:        $Date: 2003/09/16 13:41:23 $
7  * Purpose:     Hardware Timer
8  *
9  ******************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2002 SysKonnect GmbH.
14  *      (C)Copyright 2002-2003 Marvell.
15  *
16  *      This program is free software; you can redistribute it and/or modify
17  *      it under the terms of the GNU General Public License as published by
18  *      the Free Software Foundation; either version 2 of the License, or
19  *      (at your option) any later version.
20  *
21  *      The information in this file is provided "AS IS" without warranty.
22  *
23  ******************************************************************************/
24
25 /*
26  *      Event queue and dispatcher
27  */
28 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29 static const char SysKonnectFileId[] =
30         "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
31 #endif
32
33 #include "h/skdrv1st.h"         /* Driver Specific Definitions */
34 #include "h/skdrv2nd.h"         /* Adapter Control- and Driver specific Def. */
35
36 #ifdef __C2MAN__
37 /*
38  *   Hardware Timer function queue management.
39  */
40 intro()
41 {}
42 #endif
43
44 /*
45  * Prototypes of local functions.
46  */
47 #define SK_HWT_MAX      (65000)
48
49 /* correction factor */
50 #define SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
51
52 /*
53  * Initialize hardware timer.
54  *
55  * Must be called during init level 1.
56  */
57 void    SkHwtInit(
58 SK_AC   *pAC,   /* Adapters context */
59 SK_IOC  Ioc)    /* IoContext */
60 {
61         pAC->Hwt.TStart = 0 ;
62         pAC->Hwt.TStop  = 0 ;
63         pAC->Hwt.TActive = SK_FALSE;
64
65         SkHwtStop(pAC, Ioc);
66 }
67
68 /*
69  *
70  * Start hardware timer (clock ticks are 16us).
71  *
72  */
73 void    SkHwtStart(
74 SK_AC   *pAC,   /* Adapters context */
75 SK_IOC  Ioc,    /* IoContext */
76 SK_U32  Time)   /* Time in units of 16us to load the timer with. */
77 {
78         SK_U32  Cnt;
79
80         if (Time > SK_HWT_MAX)
81                 Time = SK_HWT_MAX;
82
83         pAC->Hwt.TStart = Time;
84         pAC->Hwt.TStop = 0L;
85
86         Cnt = Time;
87
88         /*
89          * if time < 16 us
90          *      time = 16 us
91          */
92         if (!Cnt) {
93                 Cnt++;
94         }
95
96         SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
97         
98         SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);   /* Start timer. */
99
100         pAC->Hwt.TActive = SK_TRUE;
101 }
102
103 /*
104  * Stop hardware timer.
105  * and clear the timer IRQ
106  */
107 void    SkHwtStop(
108 SK_AC   *pAC,   /* Adapters context */
109 SK_IOC  Ioc)    /* IoContext */
110 {
111         SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
112         
113         SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
114
115         pAC->Hwt.TActive = SK_FALSE;
116 }
117
118
119 /*
120  *      Stop hardware timer and read time elapsed since last start.
121  *
122  * returns
123  *      The elapsed time since last start in units of 16us.
124  *
125  */
126 SK_U32  SkHwtRead(
127 SK_AC   *pAC,   /* Adapters context */
128 SK_IOC  Ioc)    /* IoContext */
129 {
130         SK_U32  TRead;
131         SK_U32  IStatus;
132
133         if (pAC->Hwt.TActive) {
134                 
135                 SkHwtStop(pAC, Ioc);
136
137                 SK_IN32(Ioc, B2_TI_VAL, &TRead);
138                 TRead /= SK_HWT_FAC;
139
140                 SK_IN32(Ioc, B0_ISRC, &IStatus);
141
142                 /* Check if timer expired (or wraped around) */
143                 if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
144                         
145                         SkHwtStop(pAC, Ioc);
146                         
147                         pAC->Hwt.TStop = pAC->Hwt.TStart;
148                 }
149                 else {
150                         
151                         pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
152                 }
153         }
154         return(pAC->Hwt.TStop);
155 }
156
157 /*
158  * interrupt source= timer
159  */
160 void    SkHwtIsr(
161 SK_AC   *pAC,   /* Adapters context */
162 SK_IOC  Ioc)    /* IoContext */
163 {
164         SkHwtStop(pAC, Ioc);
165         
166         pAC->Hwt.TStop = pAC->Hwt.TStart;
167         
168         SkTimerDone(pAC, Ioc);
169 }
170
171 /* End of file */