linux/drivers/staging/cxt1e1/functions.c
<<
>>
Prefs
   1/* Copyright (C) 2003-2005  SBE, Inc.
   2 *
   3 *   This program is free software; you can redistribute it and/or modify
   4 *   it under the terms of the GNU General Public License as published by
   5 *   the Free Software Foundation; either version 2 of the License, or
   6 *   (at your option) any later version.
   7 *
   8 *   This program is distributed in the hope that it will be useful,
   9 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 *   GNU General Public License for more details.
  12 */
  13
  14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15
  16#include <linux/slab.h>
  17#include <asm/io.h>
  18#include <asm/byteorder.h>
  19#include <linux/netdevice.h>
  20#include <linux/delay.h>
  21#include <linux/hdlc.h>
  22#include "pmcc4_sysdep.h"
  23#include "sbecom_inline_linux.h"
  24#include "libsbew.h"
  25#include "pmcc4.h"
  26
  27
  28#ifdef SBE_INCLUDE_SYMBOLS
  29#define STATIC
  30#else
  31#define STATIC  static
  32#endif
  33
  34#if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \
  35    defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE)
  36#define _v7_hdlc_  1
  37#else
  38#define _v7_hdlc_  0
  39#endif
  40
  41#if _v7_hdlc_
  42#define V7(x) (x ## _v7)
  43extern int  hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *);
  44extern int  register_hdlc_device_v7 (hdlc_device *);
  45extern int  unregister_hdlc_device_v7 (hdlc_device *);
  46
  47#else
  48#define V7(x) x
  49#endif
  50
  51
  52#ifndef USE_MAX_INT_DELAY
  53static int  dummy = 0;
  54
  55#endif
  56
  57extern int  cxt1e1_log_level;
  58extern int  drvr_state;
  59
  60
  61#if 1
  62u_int32_t
  63pci_read_32 (u_int32_t *p)
  64{
  65#ifdef FLOW_DEBUG
  66    u_int32_t   v;
  67
  68    FLUSH_PCI_READ ();
  69    v = le32_to_cpu (*p);
  70    if (cxt1e1_log_level >= LOG_DEBUG)
  71        pr_info("pci_read : %x = %x\n", (u_int32_t) p, v);
  72    return v;
  73#else
  74    FLUSH_PCI_READ ();              /* */
  75    return le32_to_cpu (*p);
  76#endif
  77}
  78
  79void
  80pci_write_32 (u_int32_t *p, u_int32_t v)
  81{
  82#ifdef FLOW_DEBUG
  83    if (cxt1e1_log_level >= LOG_DEBUG)
  84        pr_info("pci_write: %x = %x\n", (u_int32_t) p, v);
  85#endif
  86    *p = cpu_to_le32 (v);
  87    FLUSH_PCI_WRITE ();             /* This routine is called from routines
  88                                     * which do multiple register writes
  89                                     * which themselves need flushing between
  90                                     * writes in order to guarantee write
  91                                     * ordering.  It is less code-cumbersome
  92                                     * to flush here-in then to investigate
  93                                     * and code the many other register
  94                                     * writing routines. */
  95}
  96#endif
  97
  98
  99void
 100pci_flush_write (ci_t * ci)
 101{
 102    volatile u_int32_t v;
 103
 104    /* issue a PCI read to flush PCI write thru bridge */
 105    v = *(u_int32_t *) &ci->reg->glcd;  /* any address would do */
 106
 107    /*
 108     * return nothing, this just reads PCI bridge interface to flush
 109     * previously written data
 110     */
 111}
 112
 113
 114STATIC void
 115watchdog_func (unsigned long arg)
 116{
 117    struct watchdog *wd = (void *) arg;
 118
 119    if (drvr_state != SBE_DRVR_AVAILABLE)
 120    {
 121        if (cxt1e1_log_level >= LOG_MONITOR)
 122            pr_warning("%s: drvr not available (%x)\n", __func__, drvr_state);
 123        return;
 124    }
 125    schedule_work (&wd->work);
 126    mod_timer (&wd->h, jiffies + wd->ticks);
 127}
 128
 129int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *c, int usec)
 130{
 131    wdp->func = f;
 132    wdp->softc = c;
 133    wdp->ticks = (HZ) * (usec / 1000) / 1000;
 134    INIT_WORK(&wdp->work, (void *)f);
 135    init_timer (&wdp->h);
 136    {
 137        ci_t       *ci = (ci_t *) c;
 138
 139        wdp->h.data = (unsigned long) &ci->wd;
 140    }
 141    wdp->h.function = watchdog_func;
 142    return 0;
 143}
 144
 145void
 146OS_uwait (int usec, char *description)
 147{
 148    int         tmp;
 149
 150    if (usec >= 1000)
 151    {
 152        mdelay (usec / 1000);
 153        /* now delay residual */
 154        tmp = (usec / 1000) * 1000; /* round */
 155        tmp = usec - tmp;           /* residual */
 156        if (tmp)
 157        {                           /* wait on residual */
 158            udelay (tmp);
 159        }
 160    } else
 161    {
 162        udelay (usec);
 163    }
 164}
 165
 166/* dummy short delay routine called as a subroutine so that compiler
 167 * does not optimize/remove its intent (a short delay)
 168 */
 169
 170void
 171OS_uwait_dummy (void)
 172{
 173#ifndef USE_MAX_INT_DELAY
 174    dummy++;
 175#else
 176    udelay (1);
 177#endif
 178}
 179
 180
 181void
 182OS_sem_init (void *sem, int state)
 183{
 184    switch (state)
 185    {
 186        case SEM_TAKEN:
 187                sema_init((struct semaphore *) sem, 0);
 188        break;
 189    case SEM_AVAILABLE:
 190            sema_init((struct semaphore *) sem, 1);
 191        break;
 192    default:                        /* otherwise, set sem.count to state's
 193                                     * value */
 194        sema_init (sem, state);
 195        break;
 196    }
 197}
 198
 199
 200int
 201sd_line_is_ok (void *user)
 202{
 203    struct net_device *ndev = (struct net_device *) user;
 204
 205    return (netif_carrier_ok (ndev));
 206}
 207
 208void
 209sd_line_is_up (void *user)
 210{
 211    struct net_device *ndev = (struct net_device *) user;
 212
 213    netif_carrier_on (ndev);
 214    return;
 215}
 216
 217void
 218sd_line_is_down (void *user)
 219{
 220    struct net_device *ndev = (struct net_device *) user;
 221
 222    netif_carrier_off (ndev);
 223    return;
 224}
 225
 226void
 227sd_disable_xmit (void *user)
 228{
 229    struct net_device *dev = (struct net_device *) user;
 230
 231    netif_stop_queue (dev);
 232    return;
 233}
 234
 235void
 236sd_enable_xmit (void *user)
 237{
 238    struct net_device *dev = (struct net_device *) user;
 239
 240    netif_wake_queue (dev);
 241    return;
 242}
 243
 244int
 245sd_queue_stopped (void *user)
 246{
 247    struct net_device *ndev = (struct net_device *) user;
 248
 249    return (netif_queue_stopped (ndev));
 250}
 251
 252void sd_recv_consume(void *token, size_t len, void *user)
 253{
 254    struct net_device *ndev = user;
 255    struct sk_buff *skb = token;
 256
 257    skb->dev = ndev;
 258    skb_put (skb, len);
 259    skb->protocol = hdlc_type_trans(skb, ndev);
 260    netif_rx(skb);
 261}
 262
 263
 264/**
 265 ** Read some reserved location w/in the COMET chip as a usable
 266 ** VMETRO trigger point or other trace marking event.
 267 **/
 268
 269#include "comet.h"
 270
 271extern ci_t *CI;                /* dummy pointer to board ZERO's data */
 272void
 273VMETRO_TRACE (void *x)
 274{
 275    u_int32_t   y = (u_int32_t) x;
 276
 277    pci_write_32 ((u_int32_t *) &CI->cpldbase->leds, y);
 278}
 279
 280
 281void
 282VMETRO_TRIGGER (ci_t * ci, int x)
 283{
 284    comet_t    *comet;
 285    volatile u_int32_t data;
 286
 287    comet = ci->port[0].cometbase;  /* default to COMET # 0 */
 288
 289    switch (x)
 290    {
 291    default:
 292    case 0:
 293        data = pci_read_32 ((u_int32_t *) &comet->__res24);     /* 0x90 */
 294        break;
 295    case 1:
 296        data = pci_read_32 ((u_int32_t *) &comet->__res25);     /* 0x94 */
 297        break;
 298    case 2:
 299        data = pci_read_32 ((u_int32_t *) &comet->__res26);     /* 0x98 */
 300        break;
 301    case 3:
 302        data = pci_read_32 ((u_int32_t *) &comet->__res27);     /* 0x9C */
 303        break;
 304    case 4:
 305        data = pci_read_32 ((u_int32_t *) &comet->__res88);     /* 0x220 */
 306        break;
 307    case 5:
 308        data = pci_read_32 ((u_int32_t *) &comet->__res89);     /* 0x224 */
 309        break;
 310    case 6:
 311        data = pci_read_32 ((u_int32_t *) &comet->__res8A);     /* 0x228 */
 312        break;
 313    case 7:
 314        data = pci_read_32 ((u_int32_t *) &comet->__res8B);     /* 0x22C */
 315        break;
 316    case 8:
 317        data = pci_read_32 ((u_int32_t *) &comet->__resA0);     /* 0x280 */
 318        break;
 319    case 9:
 320        data = pci_read_32 ((u_int32_t *) &comet->__resA1);     /* 0x284 */
 321        break;
 322    case 10:
 323        data = pci_read_32 ((u_int32_t *) &comet->__resA2);     /* 0x288 */
 324        break;
 325    case 11:
 326        data = pci_read_32 ((u_int32_t *) &comet->__resA3);     /* 0x28C */
 327        break;
 328    case 12:
 329        data = pci_read_32 ((u_int32_t *) &comet->__resA4);     /* 0x290 */
 330        break;
 331    case 13:
 332        data = pci_read_32 ((u_int32_t *) &comet->__resA5);     /* 0x294 */
 333        break;
 334    case 14:
 335        data = pci_read_32 ((u_int32_t *) &comet->__resA6);     /* 0x298 */
 336        break;
 337    case 15:
 338        data = pci_read_32 ((u_int32_t *) &comet->__resA7);     /* 0x29C */
 339        break;
 340    case 16:
 341        data = pci_read_32 ((u_int32_t *) &comet->__res74);     /* 0x1D0 */
 342        break;
 343    case 17:
 344        data = pci_read_32 ((u_int32_t *) &comet->__res75);     /* 0x1D4 */
 345        break;
 346    case 18:
 347        data = pci_read_32 ((u_int32_t *) &comet->__res76);     /* 0x1D8 */
 348        break;
 349    case 19:
 350        data = pci_read_32 ((u_int32_t *) &comet->__res77);     /* 0x1DC */
 351        break;
 352    }
 353}
 354
 355
 356/***  End-of-File  ***/
 357