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/*
  31 * Prototypes of local functions.
  32 */
  33/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
  34/*static void hwt_restart() ; */
  35
  36/************************
  37 *
  38 *      hwt_start
  39 *
  40 *      Start hardware timer (clock ticks are 16us).
  41 *
  42 *      void hwt_start(
  43 *              struct s_smc *smc,
  44 *              u_long time) ;
  45 * In
  46 *      smc - A pointer to the SMT Context structure.
  47 *
  48 *      time - The time in units of 16us to load the timer with.
  49 * Out
  50 *      Nothing.
  51 *
  52 ************************/
  53#define HWT_MAX (65000)
  54
  55void hwt_start(struct s_smc *smc, u_long time)
  56{
  57        u_short cnt ;
  58
  59        if (time > HWT_MAX)
  60                time = HWT_MAX ;
  61
  62        smc->hw.t_start = time ;
  63        smc->hw.t_stop = 0L ;
  64
  65        cnt = (u_short)time ;
  66        /*
  67         * if time < 16 us
  68         *      time = 16 us
  69         */
  70        if (!cnt)
  71                cnt++ ;
  72
  73        outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;    /* Load timer value. */
  74        outpw(ADDR(B2_TI_CRTL), TIM_START) ;            /* Start timer. */
  75
  76        smc->hw.timer_activ = TRUE ;
  77}
  78
  79/************************
  80 *
  81 *      hwt_stop
  82 *
  83 *      Stop hardware timer.
  84 *
  85 *      void hwt_stop(
  86 *              struct s_smc *smc) ;
  87 * In
  88 *      smc - A pointer to the SMT Context structure.
  89 * Out
  90 *      Nothing.
  91 *
  92 ************************/
  93void hwt_stop(struct s_smc *smc)
  94{
  95        outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
  96        outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
  97
  98        smc->hw.timer_activ = FALSE ;
  99}
 100
 101/************************
 102 *
 103 *      hwt_init
 104 *
 105 *      Initialize hardware timer.
 106 *
 107 *      void hwt_init(
 108 *              struct s_smc *smc) ;
 109 * In
 110 *      smc - A pointer to the SMT Context structure.
 111 * Out
 112 *      Nothing.
 113 *
 114 ************************/
 115void hwt_init(struct s_smc *smc)
 116{
 117        smc->hw.t_start = 0 ;
 118        smc->hw.t_stop  = 0 ;
 119        smc->hw.timer_activ = FALSE ;
 120
 121        hwt_restart(smc) ;
 122}
 123
 124/************************
 125 *
 126 *      hwt_restart
 127 *
 128 *      Clear timer interrupt.
 129 *
 130 *      void hwt_restart(
 131 *              struct s_smc *smc) ;
 132 * In
 133 *      smc - A pointer to the SMT Context structure.
 134 * Out
 135 *      Nothing.
 136 *
 137 ************************/
 138void hwt_restart(struct s_smc *smc)
 139{
 140        hwt_stop(smc) ;
 141}
 142
 143/************************
 144 *
 145 *      hwt_read
 146 *
 147 *      Stop hardware timer and read time elapsed since last start.
 148 *
 149 *      u_long hwt_read(smc) ;
 150 * In
 151 *      smc - A pointer to the SMT Context structure.
 152 * Out
 153 *      The elapsed time since last start in units of 16us.
 154 *
 155 ************************/
 156u_long hwt_read(struct s_smc *smc)
 157{
 158        u_short tr ;
 159        u_long  is ;
 160
 161        if (smc->hw.timer_activ) {
 162                hwt_stop(smc) ;
 163                tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
 164
 165                is = GET_ISR() ;
 166                /* Check if timer expired (or wraparound). */
 167                if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
 168                        hwt_restart(smc) ;
 169                        smc->hw.t_stop = smc->hw.t_start ;
 170                }
 171                else
 172                        smc->hw.t_stop = smc->hw.t_start - tr ;
 173        }
 174        return smc->hw.t_stop;
 175}
 176
 177#ifdef  PCI
 178/************************
 179 *
 180 *      hwt_quick_read
 181 *
 182 *      Stop hardware timer and read timer value and start the timer again.
 183 *
 184 *      u_long hwt_read(smc) ;
 185 * In
 186 *      smc - A pointer to the SMT Context structure.
 187 * Out
 188 *      current timer value in units of 80ns.
 189 *
 190 ************************/
 191u_long hwt_quick_read(struct s_smc *smc)
 192{
 193        u_long interval ;
 194        u_long time ;
 195
 196        interval = inpd(ADDR(B2_TI_INI)) ;
 197        outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
 198        time = inpd(ADDR(B2_TI_VAL)) ;
 199        outpd(ADDR(B2_TI_INI),time) ;
 200        outpw(ADDR(B2_TI_CRTL), TIM_START) ;
 201        outpd(ADDR(B2_TI_INI),interval) ;
 202
 203        return time;
 204}
 205
 206/************************
 207 *
 208 *      hwt_wait_time(smc,start,duration)
 209 *
 210 *      This function returnes after the amount of time is elapsed
 211 *      since the start time.
 212 * 
 213 * para start           start time
 214 *      duration        time to wait
 215 *
 216 * NOTE: The function will return immediately, if the timer is not
 217 *       started
 218 ************************/
 219void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
 220{
 221        long    diff ;
 222        long    interval ;
 223        int     wrapped ;
 224
 225        /*
 226         * check if timer is running
 227         */
 228        if (smc->hw.timer_activ == FALSE ||
 229                hwt_quick_read(smc) == hwt_quick_read(smc)) {
 230                return ;
 231        }
 232
 233        interval = inpd(ADDR(B2_TI_INI)) ;
 234        if (interval > duration) {
 235                do {
 236                        diff = (long)(start - hwt_quick_read(smc)) ;
 237                        if (diff < 0) {
 238                                diff += interval ;
 239                        }
 240                } while (diff <= duration) ;
 241        }
 242        else {
 243                diff = interval ;
 244                wrapped = 0 ;
 245                do {
 246                        if (!wrapped) {
 247                                if (hwt_quick_read(smc) >= start) {
 248                                        diff += interval ;
 249                                        wrapped = 1 ;
 250                                }
 251                        }
 252                        else {
 253                                if (hwt_quick_read(smc) < start) {
 254                                        wrapped = 0 ;
 255                                }
 256                        }
 257                } while (diff <= duration) ;
 258        }
 259}
 260#endif
 261
 262