linux/drivers/net/fddi/skfp/hwt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/******************************************************************************
   3 *
   4 *      (C)Copyright 1998,1999 SysKonnect,
   5 *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
   6 *
   7 *      See the file "skfddi.c" for further information.
   8 *
   9 *      The information in this file is provided "AS IS" without warranty.
  10 *
  11 ******************************************************************************/
  12
  13/*
  14 * Timer Driver for FBI board (timer chip 82C54)
  15 */
  16
  17/*
  18 * Modifications:
  19 *
  20 *      28-Jun-1994 sw  Edit v1.6.
  21 *                      MCA: Added support for the SK-NET FDDI-FM2 adapter. The
  22 *                       following functions have been added(+) or modified(*):
  23 *                       hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
  24 */
  25
  26#include "h/types.h"
  27#include "h/fddi.h"
  28#include "h/smc.h"
  29
  30#ifndef lint
  31static const char ID_sccs[] = "@(#)hwt.c        1.13 97/04/23 (C) SK " ;
  32#endif
  33
  34/*
  35 * Prototypes of local functions.
  36 */
  37/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
  38/*static void hwt_restart() ; */
  39
  40/************************
  41 *
  42 *      hwt_start
  43 *
  44 *      Start hardware timer (clock ticks are 16us).
  45 *
  46 *      void hwt_start(
  47 *              struct s_smc *smc,
  48 *              u_long time) ;
  49 * In
  50 *      smc - A pointer to the SMT Context structure.
  51 *
  52 *      time - The time in units of 16us to load the timer with.
  53 * Out
  54 *      Nothing.
  55 *
  56 ************************/
  57#define HWT_MAX (65000)
  58
  59void hwt_start(struct s_smc *smc, u_long time)
  60{
  61        u_short cnt ;
  62
  63        if (time > HWT_MAX)
  64                time = HWT_MAX ;
  65
  66        smc->hw.t_start = time ;
  67        smc->hw.t_stop = 0L ;
  68
  69        cnt = (u_short)time ;
  70        /*
  71         * if time < 16 us
  72         *      time = 16 us
  73         */
  74        if (!cnt)
  75                cnt++ ;
  76
  77        outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;    /* Load timer value. */
  78        outpw(ADDR(B2_TI_CRTL), TIM_START) ;            /* Start timer. */
  79
  80        smc->hw.timer_activ = TRUE ;
  81}
  82
  83/************************
  84 *
  85 *      hwt_stop
  86 *
  87 *      Stop hardware timer.
  88 *
  89 *      void hwt_stop(
  90 *              struct s_smc *smc) ;
  91 * In
  92 *      smc - A pointer to the SMT Context structure.
  93 * Out
  94 *      Nothing.
  95 *
  96 ************************/
  97void hwt_stop(struct s_smc *smc)
  98{
  99        outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
 100        outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
 101
 102        smc->hw.timer_activ = FALSE ;
 103}
 104
 105/************************
 106 *
 107 *      hwt_init
 108 *
 109 *      Initialize hardware timer.
 110 *
 111 *      void hwt_init(
 112 *              struct s_smc *smc) ;
 113 * In
 114 *      smc - A pointer to the SMT Context structure.
 115 * Out
 116 *      Nothing.
 117 *
 118 ************************/
 119void hwt_init(struct s_smc *smc)
 120{
 121        smc->hw.t_start = 0 ;
 122        smc->hw.t_stop  = 0 ;
 123        smc->hw.timer_activ = FALSE ;
 124
 125        hwt_restart(smc) ;
 126}
 127
 128/************************
 129 *
 130 *      hwt_restart
 131 *
 132 *      Clear timer interrupt.
 133 *
 134 *      void hwt_restart(
 135 *              struct s_smc *smc) ;
 136 * In
 137 *      smc - A pointer to the SMT Context structure.
 138 * Out
 139 *      Nothing.
 140 *
 141 ************************/
 142void hwt_restart(struct s_smc *smc)
 143{
 144        hwt_stop(smc) ;
 145}
 146
 147/************************
 148 *
 149 *      hwt_read
 150 *
 151 *      Stop hardware timer and read time elapsed since last start.
 152 *
 153 *      u_long hwt_read(smc) ;
 154 * In
 155 *      smc - A pointer to the SMT Context structure.
 156 * Out
 157 *      The elapsed time since last start in units of 16us.
 158 *
 159 ************************/
 160u_long hwt_read(struct s_smc *smc)
 161{
 162        u_short tr ;
 163        u_long  is ;
 164
 165        if (smc->hw.timer_activ) {
 166                hwt_stop(smc) ;
 167                tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
 168
 169                is = GET_ISR() ;
 170                /* Check if timer expired (or wraparound). */
 171                if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
 172                        hwt_restart(smc) ;
 173                        smc->hw.t_stop = smc->hw.t_start ;
 174                }
 175                else
 176                        smc->hw.t_stop = smc->hw.t_start - tr ;
 177        }
 178        return smc->hw.t_stop;
 179}
 180
 181#ifdef  PCI
 182/************************
 183 *
 184 *      hwt_quick_read
 185 *
 186 *      Stop hardware timer and read timer value and start the timer again.
 187 *
 188 *      u_long hwt_read(smc) ;
 189 * In
 190 *      smc - A pointer to the SMT Context structure.
 191 * Out
 192 *      current timer value in units of 80ns.
 193 *
 194 ************************/
 195u_long hwt_quick_read(struct s_smc *smc)
 196{
 197        u_long interval ;
 198        u_long time ;
 199
 200        interval = inpd(ADDR(B2_TI_INI)) ;
 201        outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
 202        time = inpd(ADDR(B2_TI_VAL)) ;
 203        outpd(ADDR(B2_TI_INI),time) ;
 204        outpw(ADDR(B2_TI_CRTL), TIM_START) ;
 205        outpd(ADDR(B2_TI_INI),interval) ;
 206
 207        return time;
 208}
 209
 210/************************
 211 *
 212 *      hwt_wait_time(smc,start,duration)
 213 *
 214 *      This function returnes after the amount of time is elapsed
 215 *      since the start time.
 216 * 
 217 * para start           start time
 218 *      duration        time to wait
 219 *
 220 * NOTE: The function will return immediately, if the timer is not
 221 *       started
 222 ************************/
 223void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
 224{
 225        long    diff ;
 226        long    interval ;
 227        int     wrapped ;
 228
 229        /*
 230         * check if timer is running
 231         */
 232        if (smc->hw.timer_activ == FALSE ||
 233                hwt_quick_read(smc) == hwt_quick_read(smc)) {
 234                return ;
 235        }
 236
 237        interval = inpd(ADDR(B2_TI_INI)) ;
 238        if (interval > duration) {
 239                do {
 240                        diff = (long)(start - hwt_quick_read(smc)) ;
 241                        if (diff < 0) {
 242                                diff += interval ;
 243                        }
 244                } while (diff <= duration) ;
 245        }
 246        else {
 247                diff = interval ;
 248                wrapped = 0 ;
 249                do {
 250                        if (!wrapped) {
 251                                if (hwt_quick_read(smc) >= start) {
 252                                        diff += interval ;
 253                                        wrapped = 1 ;
 254                                }
 255                        }
 256                        else {
 257                                if (hwt_quick_read(smc) < start) {
 258                                        wrapped = 0 ;
 259                                }
 260                        }
 261                } while (diff <= duration) ;
 262        }
 263}
 264#endif
 265
 266