150ee11fe383255db8e5c3307319d470015616f27Bob Beers/*-----------------------------------------------------------------------------
250ee11fe383255db8e5c3307319d470015616f27Bob Beers * pmcc4_drv.c -
350ee11fe383255db8e5c3307319d470015616f27Bob Beers *
450ee11fe383255db8e5c3307319d470015616f27Bob Beers * Copyright (C) 2007  One Stop Systems, Inc.
550ee11fe383255db8e5c3307319d470015616f27Bob Beers * Copyright (C) 2002-2006  SBE, Inc.
650ee11fe383255db8e5c3307319d470015616f27Bob Beers *
750ee11fe383255db8e5c3307319d470015616f27Bob Beers *   This program is free software; you can redistribute it and/or modify
850ee11fe383255db8e5c3307319d470015616f27Bob Beers *   it under the terms of the GNU General Public License as published by
950ee11fe383255db8e5c3307319d470015616f27Bob Beers *   the Free Software Foundation; either version 2 of the License, or
1050ee11fe383255db8e5c3307319d470015616f27Bob Beers *   (at your option) any later version.
1150ee11fe383255db8e5c3307319d470015616f27Bob Beers *
1250ee11fe383255db8e5c3307319d470015616f27Bob Beers *   This program is distributed in the hope that it will be useful,
1350ee11fe383255db8e5c3307319d470015616f27Bob Beers *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1450ee11fe383255db8e5c3307319d470015616f27Bob Beers *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1550ee11fe383255db8e5c3307319d470015616f27Bob Beers *   GNU General Public License for more details.
1650ee11fe383255db8e5c3307319d470015616f27Bob Beers *
1750ee11fe383255db8e5c3307319d470015616f27Bob Beers * For further information, contact via email: support@onestopsystems.com
1850ee11fe383255db8e5c3307319d470015616f27Bob Beers * One Stop Systems, Inc.  Escondido, California  U.S.A.
1950ee11fe383255db8e5c3307319d470015616f27Bob Beers *-----------------------------------------------------------------------------
2050ee11fe383255db8e5c3307319d470015616f27Bob Beers */
2150ee11fe383255db8e5c3307319d470015616f27Bob Beers
22e6e4d05d4d440f1989f696baa146263957593345Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2350ee11fe383255db8e5c3307319d470015616f27Bob Beers
2450ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <linux/types.h>
2550ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "pmcc4_sysdep.h"
2650ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <linux/errno.h>
2750ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <linux/kernel.h>
2850ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <linux/sched.h>        /* include for timer */
2950ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <linux/timer.h>        /* include for timer */
3050ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <linux/hdlc.h>
3150ee11fe383255db8e5c3307319d470015616f27Bob Beers#include <asm/io.h>
3250ee11fe383255db8e5c3307319d470015616f27Bob Beers
3350ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "sbecom_inline_linux.h"
3450ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "libsbew.h"
3550ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "pmcc4_private.h"
3650ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "pmcc4.h"
3750ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "pmcc4_ioctls.h"
3850ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "musycc.h"
3950ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "comet.h"
4050ee11fe383255db8e5c3307319d470015616f27Bob Beers#include "sbe_bid.h"
4150ee11fe383255db8e5c3307319d470015616f27Bob Beers
4250ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef SBE_INCLUDE_SYMBOLS
4350ee11fe383255db8e5c3307319d470015616f27Bob Beers#define STATIC
4450ee11fe383255db8e5c3307319d470015616f27Bob Beers#else
4550ee11fe383255db8e5c3307319d470015616f27Bob Beers#define STATIC  static
4650ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
4750ee11fe383255db8e5c3307319d470015616f27Bob Beers
4850ee11fe383255db8e5c3307319d470015616f27Bob Beers
4950ee11fe383255db8e5c3307319d470015616f27Bob Beers#define KERN_WARN KERN_WARNING
5050ee11fe383255db8e5c3307319d470015616f27Bob Beers
5150ee11fe383255db8e5c3307319d470015616f27Bob Beers/* forward references */
5250ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    c4_wk_chan_init (mpi_t *, mch_t *);
5350ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid        c4_wq_port_cleanup (mpi_t *);
5450ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    c4_wq_port_init (mpi_t *);
5550ee11fe383255db8e5c3307319d470015616f27Bob Beers
5650ee11fe383255db8e5c3307319d470015616f27Bob Beersint         c4_loop_port (ci_t *, int, u_int8_t);
5750ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    c4_set_port (ci_t *, int);
5850ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    musycc_chan_down (ci_t *, int);
5950ee11fe383255db8e5c3307319d470015616f27Bob Beers
6050ee11fe383255db8e5c3307319d470015616f27Bob Beersu_int32_t musycc_chan_proto (int);
6150ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    musycc_dump_ring (ci_t *, unsigned int);
6250ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t __init musycc_init (ci_t *);
6350ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid        musycc_init_mdt (mpi_t *);
6450ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid        musycc_serv_req (mpi_t *, u_int32_t);
6550ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid        musycc_update_timeslots (mpi_t *);
6650ee11fe383255db8e5c3307319d470015616f27Bob Beers
6750ee11fe383255db8e5c3307319d470015616f27Bob Beersextern void musycc_update_tx_thp (mch_t *);
68b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartmanextern int  cxt1e1_log_level;
69c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beersextern int  cxt1e1_max_mru;
70c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beersextern int  cxt1e1_max_mtu;
7150ee11fe383255db8e5c3307319d470015616f27Bob Beersextern int  max_rxdesc_used, max_rxdesc_default;
7250ee11fe383255db8e5c3307319d470015616f27Bob Beersextern int  max_txdesc_used, max_txdesc_default;
7350ee11fe383255db8e5c3307319d470015616f27Bob Beers
7450ee11fe383255db8e5c3307319d470015616f27Bob Beers#if defined (__powerpc__)
7550ee11fe383255db8e5c3307319d470015616f27Bob Beersextern void *memset (void *s, int c, size_t n);
7650ee11fe383255db8e5c3307319d470015616f27Bob Beers
7750ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
7850ee11fe383255db8e5c3307319d470015616f27Bob Beers
7950ee11fe383255db8e5c3307319d470015616f27Bob Beersint         drvr_state = SBE_DRVR_INIT;
8050ee11fe383255db8e5c3307319d470015616f27Bob Beersci_t       *c4_list = 0;
8150ee11fe383255db8e5c3307319d470015616f27Bob Beersci_t       *CI;                 /* dummy pointer to board ZEROE's data -
8250ee11fe383255db8e5c3307319d470015616f27Bob Beers                                 * DEBUG USAGE */
8350ee11fe383255db8e5c3307319d470015616f27Bob Beers
8450ee11fe383255db8e5c3307319d470015616f27Bob Beers
8550ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
8650ee11fe383255db8e5c3307319d470015616f27Bob Beerssbecom_set_loglevel (int d)
8750ee11fe383255db8e5c3307319d470015616f27Bob Beers{
8850ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*
8950ee11fe383255db8e5c3307319d470015616f27Bob Beers     * The code within the following -if- clause is a backdoor debug facility
9050ee11fe383255db8e5c3307319d470015616f27Bob Beers     * which can be used to display the state of a board's channel.
9150ee11fe383255db8e5c3307319d470015616f27Bob Beers     */
9250ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (d > LOG_DEBUG)
9350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
9450ee11fe383255db8e5c3307319d470015616f27Bob Beers        unsigned int channum = d - (LOG_DEBUG + 1);     /* convert to ZERO
9550ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                         * relativity */
9650ee11fe383255db8e5c3307319d470015616f27Bob Beers
9750ee11fe383255db8e5c3307319d470015616f27Bob Beers        (void) musycc_dump_ring ((ci_t *) CI, channum); /* CI implies support
9850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                         * for card 0 only */
9950ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
10050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
101b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        if (cxt1e1_log_level != d)
10250ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
103b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            pr_info("log level changed from %d to %d\n", cxt1e1_log_level, d);
104b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            cxt1e1_log_level = d;          /* set new */
10550ee11fe383255db8e5c3307319d470015616f27Bob Beers        } else
106b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            pr_info("log level is %d\n", cxt1e1_log_level);
10750ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
10850ee11fe383255db8e5c3307319d470015616f27Bob Beers}
10950ee11fe383255db8e5c3307319d470015616f27Bob Beers
11050ee11fe383255db8e5c3307319d470015616f27Bob Beers
11150ee11fe383255db8e5c3307319d470015616f27Bob Beersmch_t      *
11250ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_find_chan (int channum)
11350ee11fe383255db8e5c3307319d470015616f27Bob Beers{
11450ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci_t       *ci;
11550ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
11650ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         portnum, gchan;
11750ee11fe383255db8e5c3307319d470015616f27Bob Beers
11850ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (ci = c4_list; ci; ci = ci->next)
11950ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (portnum = 0; portnum < ci->max_port; portnum++)
12050ee11fe383255db8e5c3307319d470015616f27Bob Beers            for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
12150ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
12250ee11fe383255db8e5c3307319d470015616f27Bob Beers                if ((ch = ci->port[portnum].chan[gchan]))
12350ee11fe383255db8e5c3307319d470015616f27Bob Beers                {
12450ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if ((ch->state != UNASSIGNED) &&
12550ee11fe383255db8e5c3307319d470015616f27Bob Beers                        (ch->channum == channum))
12650ee11fe383255db8e5c3307319d470015616f27Bob Beers                        return (ch);
12750ee11fe383255db8e5c3307319d470015616f27Bob Beers                }
12850ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
12950ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
13050ee11fe383255db8e5c3307319d470015616f27Bob Beers}
13150ee11fe383255db8e5c3307319d470015616f27Bob Beers
13250ee11fe383255db8e5c3307319d470015616f27Bob Beers
13350ee11fe383255db8e5c3307319d470015616f27Bob Beersci_t       *__init
13450ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_new (void *hi)
13550ee11fe383255db8e5c3307319d470015616f27Bob Beers{
13650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci_t       *ci;
13750ee11fe383255db8e5c3307319d470015616f27Bob Beers
13850ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef SBE_MAP_DEBUG
139e6e4d05d4d440f1989f696baa146263957593345Joe Perches    pr_warning("c4_new() entered, ci needs %u.\n",
140e6e4d05d4d440f1989f696baa146263957593345Joe Perches               (unsigned int) sizeof (ci_t));
14150ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
14250ee11fe383255db8e5c3307319d470015616f27Bob Beers
14350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci = (ci_t *) OS_kmalloc (sizeof (ci_t));
14450ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ci)
14550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
14650ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->hdw_info = hi;
14750ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->state = C_INIT;         /* mark as hardware not available */
14850ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->next = c4_list;
14950ee11fe383255db8e5c3307319d470015616f27Bob Beers        c4_list = ci;
15050ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
15150ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
152e6e4d05d4d440f1989f696baa146263957593345Joe Perches        pr_warning("failed CI malloc, size %u.\n",
153e6e4d05d4d440f1989f696baa146263957593345Joe Perches                   (unsigned int) sizeof (ci_t));
15450ee11fe383255db8e5c3307319d470015616f27Bob Beers
15550ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (CI == 0)
15650ee11fe383255db8e5c3307319d470015616f27Bob Beers        CI = ci;                    /* DEBUG, only board 0 usage */
15750ee11fe383255db8e5c3307319d470015616f27Bob Beers    return ci;
15850ee11fe383255db8e5c3307319d470015616f27Bob Beers}
15950ee11fe383255db8e5c3307319d470015616f27Bob Beers
16050ee11fe383255db8e5c3307319d470015616f27Bob Beers
16150ee11fe383255db8e5c3307319d470015616f27Bob Beers/***
16250ee11fe383255db8e5c3307319d470015616f27Bob Beers * Check port state and set LED states using watchdog or ioctl...
16350ee11fe383255db8e5c3307319d470015616f27Bob Beers * also check for in-band SF loopback commands (& cause results if they are there)
16450ee11fe383255db8e5c3307319d470015616f27Bob Beers *
16550ee11fe383255db8e5c3307319d470015616f27Bob Beers * Alarm function depends on comet bits indicating change in
16650ee11fe383255db8e5c3307319d470015616f27Bob Beers * link status (linkMask) to keep the link status indication straight.
16750ee11fe383255db8e5c3307319d470015616f27Bob Beers *
16850ee11fe383255db8e5c3307319d470015616f27Bob Beers * Indications are only LED and system log -- except when ioctl is invoked.
16950ee11fe383255db8e5c3307319d470015616f27Bob Beers *
17050ee11fe383255db8e5c3307319d470015616f27Bob Beers * "alarmed" record (a.k.a. copyVal, in some cases below) decodes as:
17150ee11fe383255db8e5c3307319d470015616f27Bob Beers *
17250ee11fe383255db8e5c3307319d470015616f27Bob Beers *   RMAI  (E1 only) 0x100
17350ee11fe383255db8e5c3307319d470015616f27Bob Beers *   alarm LED on    0x80
17450ee11fe383255db8e5c3307319d470015616f27Bob Beers *   link LED on     0x40
17550ee11fe383255db8e5c3307319d470015616f27Bob Beers *   link returned   0x20 (link was down, now it's back and 'port get' hasn't run)
17650ee11fe383255db8e5c3307319d470015616f27Bob Beers *   change in LED   0x10 (update LED register because value has changed)
17750ee11fe383255db8e5c3307319d470015616f27Bob Beers *   link is down    0x08
17850ee11fe383255db8e5c3307319d470015616f27Bob Beers *   YelAlm(RAI)     0x04
17950ee11fe383255db8e5c3307319d470015616f27Bob Beers *   RedAlm          0x02
18050ee11fe383255db8e5c3307319d470015616f27Bob Beers *   AIS(blue)Alm    0x01
18150ee11fe383255db8e5c3307319d470015616f27Bob Beers *
18250ee11fe383255db8e5c3307319d470015616f27Bob Beers * note "link has returned" indication is reset on read
18350ee11fe383255db8e5c3307319d470015616f27Bob Beers * (e.g. by use of the c4_control port get command)
18450ee11fe383255db8e5c3307319d470015616f27Bob Beers */
18550ee11fe383255db8e5c3307319d470015616f27Bob Beers
18650ee11fe383255db8e5c3307319d470015616f27Bob Beers#define sbeLinkMask       0x41  /* change in signal status (lost/recovered) +
18750ee11fe383255db8e5c3307319d470015616f27Bob Beers                                 * state */
18850ee11fe383255db8e5c3307319d470015616f27Bob Beers#define sbeLinkChange     0x40
18950ee11fe383255db8e5c3307319d470015616f27Bob Beers#define sbeLinkDown       0x01
19050ee11fe383255db8e5c3307319d470015616f27Bob Beers#define sbeAlarmsMask     0x07  /* red / yellow / blue alarm conditions */
19150ee11fe383255db8e5c3307319d470015616f27Bob Beers#define sbeE1AlarmsMask   0x107 /* alarm conditions */
19250ee11fe383255db8e5c3307319d470015616f27Bob Beers
19350ee11fe383255db8e5c3307319d470015616f27Bob Beers#define COMET_LBCMD_READ  0x80  /* read only (do not set, return read value) */
19450ee11fe383255db8e5c3307319d470015616f27Bob Beers
19550ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
19650ee11fe383255db8e5c3307319d470015616f27Bob BeerscheckPorts (ci_t * ci)
19750ee11fe383255db8e5c3307319d470015616f27Bob Beers{
19850ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifndef CONFIG_SBE_PMCC4_NCOMM
19950ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*
20050ee11fe383255db8e5c3307319d470015616f27Bob Beers     * PORT POINT - NCOMM needs to avoid this code since the polling of
20150ee11fe383255db8e5c3307319d470015616f27Bob Beers     * alarms conflicts with NCOMM's interrupt servicing implementation.
20250ee11fe383255db8e5c3307319d470015616f27Bob Beers     */
20350ee11fe383255db8e5c3307319d470015616f27Bob Beers
20450ee11fe383255db8e5c3307319d470015616f27Bob Beers    comet_t    *comet;
20550ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t value;
20650ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int32_t   copyVal, LEDval;
20750ee11fe383255db8e5c3307319d470015616f27Bob Beers
20850ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int8_t portnum;
20950ee11fe383255db8e5c3307319d470015616f27Bob Beers
21050ee11fe383255db8e5c3307319d470015616f27Bob Beers    LEDval = 0;
21150ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (portnum = 0; portnum < ci->max_port; portnum++)
21250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
21350ee11fe383255db8e5c3307319d470015616f27Bob Beers        copyVal = 0x12f & (ci->alarmed[portnum]);       /* port's alarm record */
21450ee11fe383255db8e5c3307319d470015616f27Bob Beers        comet = ci->port[portnum].cometbase;
21550ee11fe383255db8e5c3307319d470015616f27Bob Beers        value = pci_read_32 ((u_int32_t *) &comet->cdrc_ists) & sbeLinkMask;    /* link loss reg */
21650ee11fe383255db8e5c3307319d470015616f27Bob Beers
21750ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (value & sbeLinkChange)  /* is there a change in the link stuff */
21850ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
21950ee11fe383255db8e5c3307319d470015616f27Bob Beers            /* if there's been a change (above) and yet it's the same (below) */
22050ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (!(((copyVal >> 3) & sbeLinkDown) ^ (value & sbeLinkDown)))
22150ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
22250ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value & sbeLinkDown)
223694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                    pr_warning("%s: Port %d momentarily recovered.\n",
224694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                               ci->devname, portnum);
22550ee11fe383255db8e5c3307319d470015616f27Bob Beers                else
226694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                    pr_warning("%s: Warning: Port %d link was briefly down.\n",
227694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                               ci->devname, portnum);
22850ee11fe383255db8e5c3307319d470015616f27Bob Beers            } else if (value & sbeLinkDown)
229694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                pr_warning("%s: Warning: Port %d link is down.\n",
230694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                           ci->devname, portnum);
23150ee11fe383255db8e5c3307319d470015616f27Bob Beers            else
23250ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
233694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                pr_warning("%s: Port %d link has recovered.\n",
234694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                           ci->devname, portnum);
23550ee11fe383255db8e5c3307319d470015616f27Bob Beers                copyVal |= 0x20;    /* record link transition to up */
23650ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
23750ee11fe383255db8e5c3307319d470015616f27Bob Beers            copyVal |= 0x10;        /* change (link) --> update LEDs  */
23850ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
23950ee11fe383255db8e5c3307319d470015616f27Bob Beers        copyVal &= 0x137;           /* clear LED & link old history bits &
24050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * save others */
24150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (value & sbeLinkDown)
24250ee11fe383255db8e5c3307319d470015616f27Bob Beers            copyVal |= 0x08;        /* record link status (now) */
24350ee11fe383255db8e5c3307319d470015616f27Bob Beers        else
24450ee11fe383255db8e5c3307319d470015616f27Bob Beers        {                           /* if link is up, do this */
24550ee11fe383255db8e5c3307319d470015616f27Bob Beers            copyVal |= 0x40;        /* LED indicate link is up    */
24650ee11fe383255db8e5c3307319d470015616f27Bob Beers            /* Alarm things & the like ... first if E1, then if T1 */
24750ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (IS_FRAME_ANY_E1 (ci->port[portnum].p.port_mode))
24850ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
24950ee11fe383255db8e5c3307319d470015616f27Bob Beers                /*
25050ee11fe383255db8e5c3307319d470015616f27Bob Beers                 * first check Codeword (SaX) changes & CRC and
25150ee11fe383255db8e5c3307319d470015616f27Bob Beers                 * sub-multi-frame errors
25250ee11fe383255db8e5c3307319d470015616f27Bob Beers                 */
25350ee11fe383255db8e5c3307319d470015616f27Bob Beers                /*
25450ee11fe383255db8e5c3307319d470015616f27Bob Beers                 * note these errors are printed every time they are detected
25550ee11fe383255db8e5c3307319d470015616f27Bob Beers                 * vs. alarms
25650ee11fe383255db8e5c3307319d470015616f27Bob Beers                 */
25750ee11fe383255db8e5c3307319d470015616f27Bob Beers                value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_nat_ists);   /* codeword */
25850ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value & 0x1f)
25950ee11fe383255db8e5c3307319d470015616f27Bob Beers                {                   /* if errors (crc or smf only) */
26050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x10)
261694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d Codeword Sa4 change detected.\n",
262694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
26350ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x08)
264694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d Codeword Sa5 change detected.\n",
265694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
26650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x04)
267694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d Codeword Sa6 change detected.\n",
268694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
26950ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x02)
270694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d Codeword Sa7 change detected.\n",
271694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
27250ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x01)
273694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d Codeword Sa8 change detected.\n",
274694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
27550ee11fe383255db8e5c3307319d470015616f27Bob Beers                }
27650ee11fe383255db8e5c3307319d470015616f27Bob Beers                value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_mists);      /* crc & smf */
27750ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value & 0x3)
27850ee11fe383255db8e5c3307319d470015616f27Bob Beers                {                   /* if errors (crc or smf only) */
27950ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & sbeE1CRC)
280694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d CRC-4 error(s) detected.\n",
281694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
28250ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & sbeE1errSMF)    /* error in sub-multiframe */
283694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d received errored SMF.\n",
284694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
28550ee11fe383255db8e5c3307319d470015616f27Bob Beers                }
28650ee11fe383255db8e5c3307319d470015616f27Bob Beers                value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_masts) & 0xcc; /* alarms */
28750ee11fe383255db8e5c3307319d470015616f27Bob Beers                /*
28850ee11fe383255db8e5c3307319d470015616f27Bob Beers                 * pack alarms together (bitmiser), and construct similar to
28950ee11fe383255db8e5c3307319d470015616f27Bob Beers                 * T1
29050ee11fe383255db8e5c3307319d470015616f27Bob Beers                 */
29150ee11fe383255db8e5c3307319d470015616f27Bob Beers                /* RAI,RMAI,.,.,LOF,AIS,.,. ==>  RMAI,.,.,.,.,.,RAI,LOF,AIS */
29250ee11fe383255db8e5c3307319d470015616f27Bob Beers                /* see 0x97 */
29350ee11fe383255db8e5c3307319d470015616f27Bob Beers                value = (value >> 2);
29450ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value & 0x30)
29550ee11fe383255db8e5c3307319d470015616f27Bob Beers                {
29650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x20)
29750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        value |= 0x40;  /* RAI */
29850ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if (value & 0x10)
29950ee11fe383255db8e5c3307319d470015616f27Bob Beers                        value |= 0x100; /* RMAI */
30050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    value &= ~0x30;
30150ee11fe383255db8e5c3307319d470015616f27Bob Beers                }                   /* finished packing alarm in handy order */
30250ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value != (copyVal & sbeE1AlarmsMask))
30350ee11fe383255db8e5c3307319d470015616f27Bob Beers                {                   /* if alarms changed */
30450ee11fe383255db8e5c3307319d470015616f27Bob Beers                    copyVal |= 0x10;/* change LED status   */
30550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
30650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
30750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeRedAlm;
308694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d LOF alarm ended.\n",
309694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
31050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
31150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
31250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeRedAlm;
313694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Warning: Port %d LOF alarm.\n",
314694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
31550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
31650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
31750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeYelAlm;
318694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d RAI alarm ended.\n",
319694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
32050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
32150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
32250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeYelAlm;
323694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Warning: Port %d RAI alarm.\n",
324694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
32550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if ((copyVal & sbeE1RMAI) && !(value & sbeE1RMAI))
32650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
32750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeE1RMAI;
328694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d RMAI alarm ended.\n",
329694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
33050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeE1RMAI) && (value & sbeE1RMAI))
33150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
33250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeE1RMAI;
333694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Warning: Port %d RMAI alarm.\n",
334694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
33550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
33650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
33750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeAISAlm;
338694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Port %d AIS alarm ended.\n",
339694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
34050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
34150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
34250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeAISAlm;
343694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: E1 Warning: Port %d AIS alarm.\n",
344694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
34550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    }
34650ee11fe383255db8e5c3307319d470015616f27Bob Beers                }
34750ee11fe383255db8e5c3307319d470015616f27Bob Beers                /* end of E1 alarm code */
34850ee11fe383255db8e5c3307319d470015616f27Bob Beers            } else
34950ee11fe383255db8e5c3307319d470015616f27Bob Beers            {                       /* if a T1 mode */
35050ee11fe383255db8e5c3307319d470015616f27Bob Beers                value = pci_read_32 ((u_int32_t *) &comet->t1_almi_ists);       /* alarms */
35150ee11fe383255db8e5c3307319d470015616f27Bob Beers                value &= sbeAlarmsMask;
35250ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value != (copyVal & sbeAlarmsMask))
35350ee11fe383255db8e5c3307319d470015616f27Bob Beers                {                   /* if alarms changed */
35450ee11fe383255db8e5c3307319d470015616f27Bob Beers                    copyVal |= 0x10;/* change LED status   */
35550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
35650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
35750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeRedAlm;
358694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: Port %d red alarm ended.\n",
359694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
36050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
36150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
36250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeRedAlm;
363694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: Warning: Port %d red alarm.\n",
364694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
36550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
36650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
36750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeYelAlm;
368694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: Port %d yellow (RAI) alarm ended.\n",
369694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
37050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
37150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
37250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeYelAlm;
373694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: Warning: Port %d yellow (RAI) alarm.\n",
374694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
37550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
37650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
37750ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal &= ~sbeAISAlm;
378694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: Port %d blue (AIS) alarm ended.\n",
379694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
38050ee11fe383255db8e5c3307319d470015616f27Bob Beers                    } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
38150ee11fe383255db8e5c3307319d470015616f27Bob Beers                    {
38250ee11fe383255db8e5c3307319d470015616f27Bob Beers                        copyVal |= sbeAISAlm;
383694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        pr_warning("%s: Warning: Port %d blue (AIS) alarm.\n",
384694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                                   ci->devname, portnum);
38550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    }
38650ee11fe383255db8e5c3307319d470015616f27Bob Beers                }
38750ee11fe383255db8e5c3307319d470015616f27Bob Beers            }                       /* end T1 mode alarm checks */
38850ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
38950ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (copyVal & sbeAlarmsMask)
39050ee11fe383255db8e5c3307319d470015616f27Bob Beers            copyVal |= 0x80;        /* if alarm turn yel LED on */
39150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (copyVal & 0x10)
39250ee11fe383255db8e5c3307319d470015616f27Bob Beers            LEDval |= 0x100;        /* tag if LED values have changed  */
39350ee11fe383255db8e5c3307319d470015616f27Bob Beers        LEDval |= ((copyVal & 0xc0) >> (6 - (portnum * 2)));
39450ee11fe383255db8e5c3307319d470015616f27Bob Beers
39550ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->alarmed[portnum] &= 0xfffff000;     /* out with the old (it's fff
39650ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * ... foo) */
39750ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->alarmed[portnum] |= (copyVal);      /* in with the new */
39850ee11fe383255db8e5c3307319d470015616f27Bob Beers
39950ee11fe383255db8e5c3307319d470015616f27Bob Beers        /*
40050ee11fe383255db8e5c3307319d470015616f27Bob Beers         * enough with the alarms and LED's, now let's check for loopback
40150ee11fe383255db8e5c3307319d470015616f27Bob Beers         * requests
40250ee11fe383255db8e5c3307319d470015616f27Bob Beers         */
40350ee11fe383255db8e5c3307319d470015616f27Bob Beers
40450ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (IS_FRAME_ANY_T1 (ci->port[portnum].p.port_mode))
40550ee11fe383255db8e5c3307319d470015616f27Bob Beers        {                           /* if a T1 mode  */
40650ee11fe383255db8e5c3307319d470015616f27Bob Beers            /*
40750ee11fe383255db8e5c3307319d470015616f27Bob Beers             * begin in-band (SF) loopback code detection -- start by reading
40850ee11fe383255db8e5c3307319d470015616f27Bob Beers             * command
40950ee11fe383255db8e5c3307319d470015616f27Bob Beers             */
41050ee11fe383255db8e5c3307319d470015616f27Bob Beers            value = pci_read_32 ((u_int32_t *) &comet->ibcd_ies);       /* detect reg. */
41150ee11fe383255db8e5c3307319d470015616f27Bob Beers            value &= 0x3;           /* trim to handy bits */
41250ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (value & 0x2)
41350ee11fe383255db8e5c3307319d470015616f27Bob Beers            {                       /* activate loopback (sets for deactivate
41450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * code length) */
41550ee11fe383255db8e5c3307319d470015616f27Bob Beers                copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
41650ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                         * mode */
41750ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (copyVal != COMET_MDIAG_LINELB)      /* don't do it again if
41850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                         * already in that mode */
41950ee11fe383255db8e5c3307319d470015616f27Bob Beers                    c4_loop_port (ci, portnum, COMET_MDIAG_LINELB);     /* put port in line
42050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                         * loopback mode */
42150ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
42250ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (value & 0x1)
42350ee11fe383255db8e5c3307319d470015616f27Bob Beers            {                       /* deactivate loopback (sets for activate
42450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * code length) */
42550ee11fe383255db8e5c3307319d470015616f27Bob Beers                copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
42650ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                         * mode */
42750ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (copyVal != COMET_MDIAG_LBOFF)       /* don't do it again if
42850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                         * already in that mode */
42950ee11fe383255db8e5c3307319d470015616f27Bob Beers                    c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF);      /* take port out of any
43050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                         * loopback mode */
43150ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
43250ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
43350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (IS_FRAME_ANY_T1ESF (ci->port[portnum].p.port_mode))
43450ee11fe383255db8e5c3307319d470015616f27Bob Beers        {                           /* if a T1 ESF mode  */
43550ee11fe383255db8e5c3307319d470015616f27Bob Beers            /* begin ESF loopback code */
43650ee11fe383255db8e5c3307319d470015616f27Bob Beers            value = pci_read_32 ((u_int32_t *) &comet->t1_rboc_sts) & 0x3f;     /* read command */
43750ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (value == 0x07)
43850ee11fe383255db8e5c3307319d470015616f27Bob Beers                c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line
43950ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                 * loopback mode */
44050ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (value == 0x0a)
44150ee11fe383255db8e5c3307319d470015616f27Bob Beers                c4_loop_port (ci, portnum, COMET_MDIAG_PAYLB);  /* put port in payload
44250ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                 * loopbk mode */
44350ee11fe383255db8e5c3307319d470015616f27Bob Beers            if ((value == 0x1c) || (value == 0x19) || (value == 0x12))
44450ee11fe383255db8e5c3307319d470015616f27Bob Beers                c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF);  /* take port out of any
44550ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                                 * loopbk mode */
446b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            if (cxt1e1_log_level >= LOG_DEBUG)
44750ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (value != 0x3f)
448694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                    pr_warning("%s: BOC value = %x on Port %d\n",
449694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                               ci->devname, value, portnum);
45050ee11fe383255db8e5c3307319d470015616f27Bob Beers            /* end ESF loopback code */
45150ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
45250ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
45350ee11fe383255db8e5c3307319d470015616f27Bob Beers
45450ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* if something is new, update LED's */
45550ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (LEDval & 0x100)
45650ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, LEDval & 0xff);
45750ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif                              /*** CONFIG_SBE_PMCC4_NCOMM ***/
45850ee11fe383255db8e5c3307319d470015616f27Bob Beers}
45950ee11fe383255db8e5c3307319d470015616f27Bob Beers
46050ee11fe383255db8e5c3307319d470015616f27Bob Beers
46150ee11fe383255db8e5c3307319d470015616f27Bob BeersSTATIC void
46250ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_watchdog (ci_t * ci)
46350ee11fe383255db8e5c3307319d470015616f27Bob Beers{
46450ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (drvr_state != SBE_DRVR_AVAILABLE)
46550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
466b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        if (cxt1e1_log_level >= LOG_MONITOR)
467694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("drvr not available (%x)\n", drvr_state);
46850ee11fe383255db8e5c3307319d470015616f27Bob Beers        return;
46950ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
47050ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->wdcount++;
47150ee11fe383255db8e5c3307319d470015616f27Bob Beers    checkPorts (ci);
47250ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->wd_notify = 0;
47350ee11fe383255db8e5c3307319d470015616f27Bob Beers}
47450ee11fe383255db8e5c3307319d470015616f27Bob Beers
47550ee11fe383255db8e5c3307319d470015616f27Bob Beers
47650ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
47750ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_cleanup (void)
47850ee11fe383255db8e5c3307319d470015616f27Bob Beers{
47950ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci_t       *ci, *next;
48050ee11fe383255db8e5c3307319d470015616f27Bob Beers    mpi_t      *pi;
48150ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         portnum, j;
48250ee11fe383255db8e5c3307319d470015616f27Bob Beers
48350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci = c4_list;
48450ee11fe383255db8e5c3307319d470015616f27Bob Beers    while (ci)
48550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
48650ee11fe383255db8e5c3307319d470015616f27Bob Beers        next = ci->next;            /* protect <next> from upcoming <free> */
48750ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
48850ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (portnum = 0; portnum < ci->max_port; portnum++)
48950ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
49050ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi = &ci->port[portnum];
49150ee11fe383255db8e5c3307319d470015616f27Bob Beers            c4_wq_port_cleanup (pi);
49250ee11fe383255db8e5c3307319d470015616f27Bob Beers            for (j = 0; j < MUSYCC_NCHANS; j++)
49350ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
49450ee11fe383255db8e5c3307319d470015616f27Bob Beers                if (pi->chan[j])
49550ee11fe383255db8e5c3307319d470015616f27Bob Beers                    OS_kfree (pi->chan[j]);     /* free mch_t struct */
49650ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
49750ee11fe383255db8e5c3307319d470015616f27Bob Beers            OS_kfree (pi->regram_saved);
49850ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
49950ee11fe383255db8e5c3307319d470015616f27Bob Beers        OS_kfree (ci->iqd_p_saved);
50050ee11fe383255db8e5c3307319d470015616f27Bob Beers        OS_kfree (ci);
50150ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci = next;                  /* cleanup next board, if any */
50250ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
50350ee11fe383255db8e5c3307319d470015616f27Bob Beers}
50450ee11fe383255db8e5c3307319d470015616f27Bob Beers
50550ee11fe383255db8e5c3307319d470015616f27Bob Beers
50650ee11fe383255db8e5c3307319d470015616f27Bob Beers/*
50750ee11fe383255db8e5c3307319d470015616f27Bob Beers * This function issues a write to all comet chips and expects the same data
50850ee11fe383255db8e5c3307319d470015616f27Bob Beers * to be returned from the subsequent read.  This determines the board build
50950ee11fe383255db8e5c3307319d470015616f27Bob Beers * to be a 1-port, 2-port, or 4-port build.  The value returned represents a
51050ee11fe383255db8e5c3307319d470015616f27Bob Beers * bit-mask of the found ports.  Only certain configurations are considered
51150ee11fe383255db8e5c3307319d470015616f27Bob Beers * VALID or LEGAL builds.
51250ee11fe383255db8e5c3307319d470015616f27Bob Beers */
51350ee11fe383255db8e5c3307319d470015616f27Bob Beers
51450ee11fe383255db8e5c3307319d470015616f27Bob Beersint
51550ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_get_portcfg (ci_t * ci)
51650ee11fe383255db8e5c3307319d470015616f27Bob Beers{
51750ee11fe383255db8e5c3307319d470015616f27Bob Beers    comet_t    *comet;
51850ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         portnum, mask;
51950ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int32_t   wdata, rdata;
52050ee11fe383255db8e5c3307319d470015616f27Bob Beers
52150ee11fe383255db8e5c3307319d470015616f27Bob Beers    wdata = COMET_MDIAG_LBOFF;      /* take port out of any loopback mode */
52250ee11fe383255db8e5c3307319d470015616f27Bob Beers
52350ee11fe383255db8e5c3307319d470015616f27Bob Beers    mask = 0;
52450ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
52550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
52650ee11fe383255db8e5c3307319d470015616f27Bob Beers        comet = ci->port[portnum].cometbase;
52750ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) &comet->mdiag, wdata);
52850ee11fe383255db8e5c3307319d470015616f27Bob Beers        rdata = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
52950ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (wdata == rdata)
53050ee11fe383255db8e5c3307319d470015616f27Bob Beers            mask |= 1 << portnum;
53150ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
53250ee11fe383255db8e5c3307319d470015616f27Bob Beers    return mask;
53350ee11fe383255db8e5c3307319d470015616f27Bob Beers}
53450ee11fe383255db8e5c3307319d470015616f27Bob Beers
53550ee11fe383255db8e5c3307319d470015616f27Bob Beers
53650ee11fe383255db8e5c3307319d470015616f27Bob Beers/* nothing herein should generate interrupts */
53750ee11fe383255db8e5c3307319d470015616f27Bob Beers
53850ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    __init
53950ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_init (ci_t * ci, u_char *func0, u_char *func1)
54050ee11fe383255db8e5c3307319d470015616f27Bob Beers{
54150ee11fe383255db8e5c3307319d470015616f27Bob Beers    mpi_t      *pi;
54250ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
54350ee11fe383255db8e5c3307319d470015616f27Bob Beers    static u_int32_t count = 0;
54450ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         portnum, j;
54550ee11fe383255db8e5c3307319d470015616f27Bob Beers
54650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->state = C_INIT;
54750ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->brdno = count++;
54850ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->intlog.this_status_new = 0;
54950ee11fe383255db8e5c3307319d470015616f27Bob Beers    atomic_set (&ci->bh_pending, 0);
55050ee11fe383255db8e5c3307319d470015616f27Bob Beers
55150ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->reg = (struct musycc_globalr *) func0;
55250ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->eeprombase = (u_int32_t *) (func1 + EEPROM_OFFSET);
55350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->cpldbase = (c4cpld_t *) ((u_int32_t *) (func1 + ISPLD_OFFSET));
55450ee11fe383255db8e5c3307319d470015616f27Bob Beers
55550ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*** PORT POINT - the following is the first access of any type to the hardware ***/
55650ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef CONFIG_SBE_PMCC4_NCOMM
55750ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* NCOMM driver uses INTB interrupt to monitor CPLD register */
55850ee11fe383255db8e5c3307319d470015616f27Bob Beers    pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC);
55950ee11fe383255db8e5c3307319d470015616f27Bob Beers#else
56050ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* standard driver POLLS for INTB via CPLD register */
56150ee11fe383255db8e5c3307319d470015616f27Bob Beers    pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
56250ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
56350ee11fe383255db8e5c3307319d470015616f27Bob Beers
56450ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
56550ee11fe383255db8e5c3307319d470015616f27Bob Beers        int         pmsk;
56650ee11fe383255db8e5c3307319d470015616f27Bob Beers
56750ee11fe383255db8e5c3307319d470015616f27Bob Beers        /* need comet addresses available for determination of hardware build */
56850ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
56950ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
57050ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi = &ci->port[portnum];
57150ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->cometbase = (comet_t *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum)));
57250ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800));
57350ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->portnum = portnum;
57450ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->p.portnum = portnum;
57550ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->openchans = 0;
57650ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef SBE_MAP_DEBUG
577694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("Comet-%d: addr = %p\n", portnum, pi->cometbase);
57850ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
57950ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
58050ee11fe383255db8e5c3307319d470015616f27Bob Beers        pmsk = c4_get_portcfg (ci);
58150ee11fe383255db8e5c3307319d470015616f27Bob Beers        switch (pmsk)
58250ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
58350ee11fe383255db8e5c3307319d470015616f27Bob Beers        case 0x1:
58450ee11fe383255db8e5c3307319d470015616f27Bob Beers            ci->max_port = 1;
58550ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
58650ee11fe383255db8e5c3307319d470015616f27Bob Beers        case 0x3:
58750ee11fe383255db8e5c3307319d470015616f27Bob Beers            ci->max_port = 2;
58850ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
58950ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 0
59050ee11fe383255db8e5c3307319d470015616f27Bob Beers        case 0x7:                   /* not built, but could be... */
59150ee11fe383255db8e5c3307319d470015616f27Bob Beers            ci->max_port = 3;
59250ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
59350ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
59450ee11fe383255db8e5c3307319d470015616f27Bob Beers        case 0xf:
59550ee11fe383255db8e5c3307319d470015616f27Bob Beers            ci->max_port = 4;
59650ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
59750ee11fe383255db8e5c3307319d470015616f27Bob Beers        default:
59850ee11fe383255db8e5c3307319d470015616f27Bob Beers            ci->max_port = 0;
599e6e4d05d4d440f1989f696baa146263957593345Joe Perches            pr_warning("%s: illegal port configuration (%x)\n",
600e6e4d05d4d440f1989f696baa146263957593345Joe Perches                       ci->devname, pmsk);
60150ee11fe383255db8e5c3307319d470015616f27Bob Beers            return SBE_DRVR_FAIL;
60250ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
60350ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef SBE_MAP_DEBUG
604694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info(">> %s: c4_get_build - pmsk %x max_port %x\n",
605694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                ci->devname, pmsk, ci->max_port);
60650ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
60750ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
60850ee11fe383255db8e5c3307319d470015616f27Bob Beers
60950ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (portnum = 0; portnum < ci->max_port; portnum++)
61050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
61150ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi = &ci->port[portnum];
61250ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->up = ci;
61350ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->sr_last = 0xffffffff;
61450ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->p.port_mode = CFG_FRAME_SF; /* T1 B8ZS, the default */
61550ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->p.portP = (CFG_CLK_PORT_EXTERNAL | CFG_LBO_LH0);    /* T1 defaults */
61650ee11fe383255db8e5c3307319d470015616f27Bob Beers
61750ee11fe383255db8e5c3307319d470015616f27Bob Beers        OS_sem_init (&pi->sr_sem_busy, SEM_AVAILABLE);
61850ee11fe383255db8e5c3307319d470015616f27Bob Beers        OS_sem_init (&pi->sr_sem_wait, SEM_TAKEN);
61950ee11fe383255db8e5c3307319d470015616f27Bob Beers
62050ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (j = 0; j < 32; j++)
62150ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
62250ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->fifomap[j] = -1;
62350ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->tsm[j] = 0;         /* no assignments, all available */
62450ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
62550ee11fe383255db8e5c3307319d470015616f27Bob Beers
62650ee11fe383255db8e5c3307319d470015616f27Bob Beers        /* allocate channel structures for this port */
62750ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (j = 0; j < MUSYCC_NCHANS; j++)
62850ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
62950ee11fe383255db8e5c3307319d470015616f27Bob Beers            ch = OS_kmalloc (sizeof (mch_t));
63050ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (ch)
63150ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
63250ee11fe383255db8e5c3307319d470015616f27Bob Beers                pi->chan[j] = ch;
63350ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->state = UNASSIGNED;
63450ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->up = pi;
63550ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->gchan = (-1);   /* channel assignment not yet known */
63650ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->channum = (-1); /* channel assignment not yet known */
63750ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->p.card = ci->brdno;
63850ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->p.port = portnum;
63950ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->p.channum = (-1);   /* channel assignment not yet known */
64050ee11fe383255db8e5c3307319d470015616f27Bob Beers                ch->p.mode_56k = 0; /* default is 64kbps mode */
64150ee11fe383255db8e5c3307319d470015616f27Bob Beers            } else
64250ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
643e6e4d05d4d440f1989f696baa146263957593345Joe Perches                pr_warning("failed mch_t malloc, port %d channel %d size %u.\n",
644e6e4d05d4d440f1989f696baa146263957593345Joe Perches                           portnum, j, (unsigned int) sizeof (mch_t));
64550ee11fe383255db8e5c3307319d470015616f27Bob Beers                break;
64650ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
64750ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
64850ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
64950ee11fe383255db8e5c3307319d470015616f27Bob Beers
65050ee11fe383255db8e5c3307319d470015616f27Bob Beers
65150ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
65250ee11fe383255db8e5c3307319d470015616f27Bob Beers        /*
65350ee11fe383255db8e5c3307319d470015616f27Bob Beers         * Set LEDs through their paces to supply visual proof that LEDs are
65450ee11fe383255db8e5c3307319d470015616f27Bob Beers         * functional and not burnt out nor broken.
65550ee11fe383255db8e5c3307319d470015616f27Bob Beers         *
65650ee11fe383255db8e5c3307319d470015616f27Bob Beers         * YELLOW + GREEN -> OFF.
65750ee11fe383255db8e5c3307319d470015616f27Bob Beers         */
65850ee11fe383255db8e5c3307319d470015616f27Bob Beers
65950ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) &ci->cpldbase->leds,
66050ee11fe383255db8e5c3307319d470015616f27Bob Beers                      PMCC4_CPLD_LED_GREEN | PMCC4_CPLD_LED_YELLOW);
66150ee11fe383255db8e5c3307319d470015616f27Bob Beers        OS_uwait (750000, "leds");
66250ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
66350ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
66450ee11fe383255db8e5c3307319d470015616f27Bob Beers
66550ee11fe383255db8e5c3307319d470015616f27Bob Beers    OS_init_watchdog (&ci->wd, (void (*) (void *)) c4_watchdog, ci, WATCHDOG_TIMEOUT);
66650ee11fe383255db8e5c3307319d470015616f27Bob Beers    return SBE_DRVR_SUCCESS;
66750ee11fe383255db8e5c3307319d470015616f27Bob Beers}
66850ee11fe383255db8e5c3307319d470015616f27Bob Beers
66950ee11fe383255db8e5c3307319d470015616f27Bob Beers
67050ee11fe383255db8e5c3307319d470015616f27Bob Beers/* better be fully setup to handle interrupts when you call this */
67150ee11fe383255db8e5c3307319d470015616f27Bob Beers
67250ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t    __init
67350ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_init2 (ci_t * ci)
67450ee11fe383255db8e5c3307319d470015616f27Bob Beers{
67550ee11fe383255db8e5c3307319d470015616f27Bob Beers    status_t    ret;
67650ee11fe383255db8e5c3307319d470015616f27Bob Beers
67750ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* PORT POINT: this routine generates first interrupt */
67850ee11fe383255db8e5c3307319d470015616f27Bob Beers    if ((ret = musycc_init (ci)) != SBE_DRVR_SUCCESS)
67950ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ret;
68050ee11fe383255db8e5c3307319d470015616f27Bob Beers
68150ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 0
68250ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->p.framing_type = FRAMING_CBP;
68350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->p.h110enable = 1;
68450ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 0
68550ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->p.hypersize = 0;
68650ee11fe383255db8e5c3307319d470015616f27Bob Beers#else
68750ee11fe383255db8e5c3307319d470015616f27Bob Beers    hyperdummy = 0;
68850ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
68950ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->p.clock = 0;                /* Use internal clocking until set to
69050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * external */
69150ee11fe383255db8e5c3307319d470015616f27Bob Beers    c4_card_set_params (ci, &ci->p);
69250ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
69350ee11fe383255db8e5c3307319d470015616f27Bob Beers    OS_start_watchdog (&ci->wd);
69450ee11fe383255db8e5c3307319d470015616f27Bob Beers    return SBE_DRVR_SUCCESS;
69550ee11fe383255db8e5c3307319d470015616f27Bob Beers}
69650ee11fe383255db8e5c3307319d470015616f27Bob Beers
69750ee11fe383255db8e5c3307319d470015616f27Bob Beers
69850ee11fe383255db8e5c3307319d470015616f27Bob Beers/* This function sets the loopback mode (or clears it, as the case may be). */
69950ee11fe383255db8e5c3307319d470015616f27Bob Beers
70050ee11fe383255db8e5c3307319d470015616f27Bob Beersint
70150ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_loop_port (ci_t * ci, int portnum, u_int8_t cmd)
70250ee11fe383255db8e5c3307319d470015616f27Bob Beers{
70350ee11fe383255db8e5c3307319d470015616f27Bob Beers    comet_t    *comet;
70450ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t loopValue;
70550ee11fe383255db8e5c3307319d470015616f27Bob Beers
70650ee11fe383255db8e5c3307319d470015616f27Bob Beers    comet = ci->port[portnum].cometbase;
70750ee11fe383255db8e5c3307319d470015616f27Bob Beers    loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
70850ee11fe383255db8e5c3307319d470015616f27Bob Beers
70950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (cmd & COMET_LBCMD_READ)
71050ee11fe383255db8e5c3307319d470015616f27Bob Beers        return loopValue;           /* return the read value */
71150ee11fe383255db8e5c3307319d470015616f27Bob Beers
71250ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (loopValue != cmd)
71350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
71450ee11fe383255db8e5c3307319d470015616f27Bob Beers        switch (cmd)
71550ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
71650ee11fe383255db8e5c3307319d470015616f27Bob Beers        case COMET_MDIAG_LINELB:
71750ee11fe383255db8e5c3307319d470015616f27Bob Beers            /* set(SF)loopback down (turn off) code length to 6 bits */
71850ee11fe383255db8e5c3307319d470015616f27Bob Beers            pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x05);
71950ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
72050ee11fe383255db8e5c3307319d470015616f27Bob Beers        case COMET_MDIAG_LBOFF:
72150ee11fe383255db8e5c3307319d470015616f27Bob Beers            /* set (SF) loopback up (turn on) code length to 5 bits */
72250ee11fe383255db8e5c3307319d470015616f27Bob Beers            pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x00);
72350ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
72450ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
72550ee11fe383255db8e5c3307319d470015616f27Bob Beers
72650ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) &comet->mdiag, cmd);
727b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        if (cxt1e1_log_level >= LOG_WARN)
728694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("%s: loopback mode changed to %2x from %2x on Port %d\n",
72950ee11fe383255db8e5c3307319d470015616f27Bob Beers                    ci->devname, cmd, loopValue, portnum);
73050ee11fe383255db8e5c3307319d470015616f27Bob Beers        loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
73150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (loopValue != cmd)
73250ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
733b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            if (cxt1e1_log_level >= LOG_ERROR)
734694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                pr_info("%s: write to loop register failed, unknown state for Port %d\n",
73550ee11fe383255db8e5c3307319d470015616f27Bob Beers                        ci->devname, portnum);
73650ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
73750ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
73850ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
739b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        if (cxt1e1_log_level >= LOG_WARN)
740694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("%s: loopback already in that mode (%2x)\n",
741694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                    ci->devname, loopValue);
74250ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
74350ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
74450ee11fe383255db8e5c3307319d470015616f27Bob Beers}
74550ee11fe383255db8e5c3307319d470015616f27Bob Beers
74650ee11fe383255db8e5c3307319d470015616f27Bob Beers
74750ee11fe383255db8e5c3307319d470015616f27Bob Beers/* c4_frame_rw: read or write the comet register specified
74850ee11fe383255db8e5c3307319d470015616f27Bob Beers * (modifies use of port_param to non-standard use of struct)
74950ee11fe383255db8e5c3307319d470015616f27Bob Beers * Specifically:
75050ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portnum     (one guess)
75150ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.port_mode   offset of register
75250ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portP       write (or not, i.e. read)
75350ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portStatus  write value
75450ee11fe383255db8e5c3307319d470015616f27Bob Beers * BTW:
75550ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portStatus  also used to return read value
75650ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portP       also used during write, to return old reg value
75750ee11fe383255db8e5c3307319d470015616f27Bob Beers */
75850ee11fe383255db8e5c3307319d470015616f27Bob Beers
75950ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
76050ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_frame_rw (ci_t * ci, struct sbecom_port_param * pp)
76150ee11fe383255db8e5c3307319d470015616f27Bob Beers{
76250ee11fe383255db8e5c3307319d470015616f27Bob Beers    comet_t    *comet;
76350ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t data;
76450ee11fe383255db8e5c3307319d470015616f27Bob Beers
76550ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (pp->portnum >= ci->max_port)/* sanity check */
76650ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENXIO;
76750ee11fe383255db8e5c3307319d470015616f27Bob Beers
76850ee11fe383255db8e5c3307319d470015616f27Bob Beers    comet = ci->port[pp->portnum].cometbase;
76950ee11fe383255db8e5c3307319d470015616f27Bob Beers    data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
77050ee11fe383255db8e5c3307319d470015616f27Bob Beers
77150ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (pp->portP)
77250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {                               /* control says this is a register
77350ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * _write_ */
77450ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (pp->portStatus == data)
775694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("%s: Port %d already that value!  Writing again anyhow.\n",
77650ee11fe383255db8e5c3307319d470015616f27Bob Beers                    ci->devname, pp->portnum);
77750ee11fe383255db8e5c3307319d470015616f27Bob Beers        pp->portP = (u_int8_t) data;
77850ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) comet + pp->port_mode,
77950ee11fe383255db8e5c3307319d470015616f27Bob Beers                      pp->portStatus);
78050ee11fe383255db8e5c3307319d470015616f27Bob Beers        data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
78150ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
78250ee11fe383255db8e5c3307319d470015616f27Bob Beers    pp->portStatus = (u_int8_t) data;
78350ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
78450ee11fe383255db8e5c3307319d470015616f27Bob Beers}
78550ee11fe383255db8e5c3307319d470015616f27Bob Beers
78650ee11fe383255db8e5c3307319d470015616f27Bob Beers
78750ee11fe383255db8e5c3307319d470015616f27Bob Beers/* c4_pld_rw: read or write the pld register specified
78850ee11fe383255db8e5c3307319d470015616f27Bob Beers * (modifies use of port_param to non-standard use of struct)
78950ee11fe383255db8e5c3307319d470015616f27Bob Beers * Specifically:
79050ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.port_mode   offset of register
79150ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portP       write (or not, i.e. read)
79250ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portStatus  write value
79350ee11fe383255db8e5c3307319d470015616f27Bob Beers * BTW:
79450ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portStatus  also used to return read value
79550ee11fe383255db8e5c3307319d470015616f27Bob Beers *   pp.portP       also used during write, to return old reg value
79650ee11fe383255db8e5c3307319d470015616f27Bob Beers */
79750ee11fe383255db8e5c3307319d470015616f27Bob Beers
79850ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
79950ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_pld_rw (ci_t * ci, struct sbecom_port_param * pp)
80050ee11fe383255db8e5c3307319d470015616f27Bob Beers{
80150ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t *regaddr;
80250ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t data;
80350ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         regnum = pp->port_mode;
80450ee11fe383255db8e5c3307319d470015616f27Bob Beers
80550ee11fe383255db8e5c3307319d470015616f27Bob Beers    regaddr = (u_int32_t *) ci->cpldbase + regnum;
80650ee11fe383255db8e5c3307319d470015616f27Bob Beers    data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
80750ee11fe383255db8e5c3307319d470015616f27Bob Beers
80850ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (pp->portP)
80950ee11fe383255db8e5c3307319d470015616f27Bob Beers    {                               /* control says this is a register
81050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * _write_ */
81150ee11fe383255db8e5c3307319d470015616f27Bob Beers        pp->portP = (u_int8_t) data;
81250ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) regaddr, pp->portStatus);
81350ee11fe383255db8e5c3307319d470015616f27Bob Beers        data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
81450ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
81550ee11fe383255db8e5c3307319d470015616f27Bob Beers    pp->portStatus = (u_int8_t) data;
81650ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
81750ee11fe383255db8e5c3307319d470015616f27Bob Beers}
81850ee11fe383255db8e5c3307319d470015616f27Bob Beers
81950ee11fe383255db8e5c3307319d470015616f27Bob Beers/* c4_musycc_rw: read or write the musycc register specified
82050ee11fe383255db8e5c3307319d470015616f27Bob Beers * (modifies use of port_param to non-standard use of struct)
82150ee11fe383255db8e5c3307319d470015616f27Bob Beers * Specifically:
82250ee11fe383255db8e5c3307319d470015616f27Bob Beers *    mcp.RWportnum   port number and write indication bit (0x80)
82350ee11fe383255db8e5c3307319d470015616f27Bob Beers *    mcp.offset      offset of register
82450ee11fe383255db8e5c3307319d470015616f27Bob Beers *    mcp.value       write value going in and read value returning
82550ee11fe383255db8e5c3307319d470015616f27Bob Beers */
82650ee11fe383255db8e5c3307319d470015616f27Bob Beers
82750ee11fe383255db8e5c3307319d470015616f27Bob Beers/* PORT POINT: TX Subchannel Map registers are write-only
82850ee11fe383255db8e5c3307319d470015616f27Bob Beers * areas within the MUSYCC and always return FF */
82950ee11fe383255db8e5c3307319d470015616f27Bob Beers/* PORT POINT: regram and reg structures are minorly different and <offset> ioctl
83050ee11fe383255db8e5c3307319d470015616f27Bob Beers * settings are aligned with the <reg> struct musycc_globalr{} usage.
83150ee11fe383255db8e5c3307319d470015616f27Bob Beers * Also, regram is separately allocated shared memory, allocated for each port.
83250ee11fe383255db8e5c3307319d470015616f27Bob Beers * PORT POINT: access offsets of 0x6000 for Msg Cfg Desc Tbl are for 4-port MUSYCC
83350ee11fe383255db8e5c3307319d470015616f27Bob Beers * only.  (An 8-port MUSYCC has 0x16000 offsets for accessing its upper 4 tables.)
83450ee11fe383255db8e5c3307319d470015616f27Bob Beers */
83550ee11fe383255db8e5c3307319d470015616f27Bob Beers
83650ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
83750ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_musycc_rw (ci_t * ci, struct c4_musycc_param * mcp)
83850ee11fe383255db8e5c3307319d470015616f27Bob Beers{
83950ee11fe383255db8e5c3307319d470015616f27Bob Beers    mpi_t      *pi;
84050ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t *dph;    /* hardware implemented register */
84150ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int32_t  *dpr = 0;        /* RAM image of registers for group command
84250ee11fe383255db8e5c3307319d470015616f27Bob Beers                                 * usage */
84350ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         offset = mcp->offset % 0x800;   /* group relative address
84450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * offset, mcp->portnum is
84550ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * not used */
84650ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         portnum, ramread = 0;
84750ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t data;
84850ee11fe383255db8e5c3307319d470015616f27Bob Beers
84950ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*
85050ee11fe383255db8e5c3307319d470015616f27Bob Beers     * Sanity check hardware accessibility.  The 0x6000 portion handles port
85150ee11fe383255db8e5c3307319d470015616f27Bob Beers     * numbers associated with Msg Descr Tbl decoding.
85250ee11fe383255db8e5c3307319d470015616f27Bob Beers     */
85350ee11fe383255db8e5c3307319d470015616f27Bob Beers    portnum = (mcp->offset % 0x6000) / 0x800;
85450ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (portnum >= ci->max_port)
85550ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENXIO;
85650ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi = &ci->port[portnum];
85750ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (mcp->offset >= 0x6000)
85850ee11fe383255db8e5c3307319d470015616f27Bob Beers        offset += 0x6000;           /* put back in MsgCfgDesc address offset */
85950ee11fe383255db8e5c3307319d470015616f27Bob Beers    dph = (u_int32_t *) ((u_long) pi->reg + offset);
86050ee11fe383255db8e5c3307319d470015616f27Bob Beers
86150ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* read of TX are from RAM image, since hardware returns FF */
86250ee11fe383255db8e5c3307319d470015616f27Bob Beers    dpr = (u_int32_t *) ((u_long) pi->regram + offset);
86350ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (mcp->offset < 0x6000)       /* non MsgDesc Tbl accesses might require
86450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * RAM access */
86550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
86650ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (offset >= 0x200 && offset < 0x380)
86750ee11fe383255db8e5c3307319d470015616f27Bob Beers            ramread = 1;
86850ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (offset >= 0x10 && offset < 0x200)
86950ee11fe383255db8e5c3307319d470015616f27Bob Beers            ramread = 1;
87050ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
87150ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* read register from RAM or hardware, depending... */
87250ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ramread)
87350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
87450ee11fe383255db8e5c3307319d470015616f27Bob Beers        data = *dpr;
875694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        //pr_info("c4_musycc_rw: RAM addr %p  read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */
87650ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
87750ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
87850ee11fe383255db8e5c3307319d470015616f27Bob Beers        data = pci_read_32 ((u_int32_t *) dph);
879694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        //pr_info("c4_musycc_rw: REG addr %p  read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */
88050ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
88150ee11fe383255db8e5c3307319d470015616f27Bob Beers
88250ee11fe383255db8e5c3307319d470015616f27Bob Beers
88350ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (mcp->RWportnum & 0x80)
88450ee11fe383255db8e5c3307319d470015616f27Bob Beers    {                               /* control says this is a register
88550ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * _write_ */
88650ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (mcp->value == data)
887694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("%s: musycc grp%d already that value! writing again anyhow.\n",
88850ee11fe383255db8e5c3307319d470015616f27Bob Beers                    ci->devname, (mcp->RWportnum & 0x7));
88950ee11fe383255db8e5c3307319d470015616f27Bob Beers        /* write register RAM */
89050ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ramread)
89150ee11fe383255db8e5c3307319d470015616f27Bob Beers            *dpr = mcp->value;
89250ee11fe383255db8e5c3307319d470015616f27Bob Beers        /* write hardware register */
89350ee11fe383255db8e5c3307319d470015616f27Bob Beers        pci_write_32 ((u_int32_t *) dph, mcp->value);
89450ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
89550ee11fe383255db8e5c3307319d470015616f27Bob Beers    mcp->value = data;              /* return the read value (or the 'old
89650ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * value', if is write) */
89750ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
89850ee11fe383255db8e5c3307319d470015616f27Bob Beers}
89950ee11fe383255db8e5c3307319d470015616f27Bob Beers
90050ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
90150ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_get_port (ci_t * ci, int portnum)
90250ee11fe383255db8e5c3307319d470015616f27Bob Beers{
90350ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (portnum >= ci->max_port)    /* sanity check */
90450ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENXIO;
90550ee11fe383255db8e5c3307319d470015616f27Bob Beers
90650ee11fe383255db8e5c3307319d470015616f27Bob Beers    SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_");      /* only 1 thru here, per
90750ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * board */
90850ee11fe383255db8e5c3307319d470015616f27Bob Beers    checkPorts (ci);
90950ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->port[portnum].p.portStatus = (u_int8_t) ci->alarmed[portnum];
91050ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci->alarmed[portnum] &= 0xdf;
91150ee11fe383255db8e5c3307319d470015616f27Bob Beers    SD_SEM_GIVE (&ci->sem_wdbusy);  /* release per-board hold */
91250ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
91350ee11fe383255db8e5c3307319d470015616f27Bob Beers}
91450ee11fe383255db8e5c3307319d470015616f27Bob Beers
91550ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
91650ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_set_port (ci_t * ci, int portnum)
91750ee11fe383255db8e5c3307319d470015616f27Bob Beers{
91850ee11fe383255db8e5c3307319d470015616f27Bob Beers    mpi_t      *pi;
91950ee11fe383255db8e5c3307319d470015616f27Bob Beers    struct sbecom_port_param *pp;
92050ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         e1mode;
92150ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int8_t    clck;
92250ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         i;
92350ee11fe383255db8e5c3307319d470015616f27Bob Beers
92450ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (portnum >= ci->max_port)    /* sanity check */
92550ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENXIO;
92650ee11fe383255db8e5c3307319d470015616f27Bob Beers
92750ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi = &ci->port[portnum];
92850ee11fe383255db8e5c3307319d470015616f27Bob Beers    pp = &ci->port[portnum].p;
92950ee11fe383255db8e5c3307319d470015616f27Bob Beers    e1mode = IS_FRAME_ANY_E1 (pp->port_mode);
930b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman    if (cxt1e1_log_level >= LOG_MONITOR2)
93150ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
932694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("%s: c4_set_port[%d]:  entered, e1mode = %x, openchans %d.\n",
93350ee11fe383255db8e5c3307319d470015616f27Bob Beers                ci->devname,
93450ee11fe383255db8e5c3307319d470015616f27Bob Beers                portnum, e1mode, pi->openchans);
93550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
93650ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (pi->openchans)
93750ee11fe383255db8e5c3307319d470015616f27Bob Beers        return EBUSY;               /* group needs initialization only for
93850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * first channel of a group */
93950ee11fe383255db8e5c3307319d470015616f27Bob Beers
94050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
94150ee11fe383255db8e5c3307319d470015616f27Bob Beers        status_t    ret;
94250ee11fe383255db8e5c3307319d470015616f27Bob Beers
94350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if ((ret = c4_wq_port_init (pi)))       /* create/init
94450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * workqueue_struct */
94550ee11fe383255db8e5c3307319d470015616f27Bob Beers            return (ret);
94650ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
94750ee11fe383255db8e5c3307319d470015616f27Bob Beers
94850ee11fe383255db8e5c3307319d470015616f27Bob Beers    init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP);
94950ee11fe383255db8e5c3307319d470015616f27Bob Beers    clck = pci_read_32 ((u_int32_t *) &ci->cpldbase->mclk) & PMCC4_CPLD_MCLK_MASK;
95050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (e1mode)
95150ee11fe383255db8e5c3307319d470015616f27Bob Beers        clck |= 1 << portnum;
95250ee11fe383255db8e5c3307319d470015616f27Bob Beers    else
95350ee11fe383255db8e5c3307319d470015616f27Bob Beers        clck &= 0xf ^ (1 << portnum);
95450ee11fe383255db8e5c3307319d470015616f27Bob Beers
95550ee11fe383255db8e5c3307319d470015616f27Bob Beers    pci_write_32 ((u_int32_t *) &ci->cpldbase->mclk, clck);
95650ee11fe383255db8e5c3307319d470015616f27Bob Beers    pci_write_32 ((u_int32_t *) &ci->cpldbase->mcsr, PMCC4_CPLD_MCSR_IND);
95750ee11fe383255db8e5c3307319d470015616f27Bob Beers    pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram));
95850ee11fe383255db8e5c3307319d470015616f27Bob Beers
95950ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*********************************************************************/
96050ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* ERRATA: If transparent mode is used, do not set OOFMP_DISABLE bit */
96150ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*********************************************************************/
96250ee11fe383255db8e5c3307319d470015616f27Bob Beers
96350ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->regram->grcd =
96450ee11fe383255db8e5c3307319d470015616f27Bob Beers        __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE |
96550ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_GRCD_TX_ENABLE |
96650ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_GRCD_OOFMP_DISABLE |
96750ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_GRCD_SF_ALIGN |  /* per MUSYCC ERRATA,
96850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                         * for T1 * fix */
96950ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_GRCD_COFAIRQ_DISABLE |
97050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_GRCD_MC_ENABLE |
97150ee11fe383255db8e5c3307319d470015616f27Bob Beers                       (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
97250ee11fe383255db8e5c3307319d470015616f27Bob Beers
97350ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->regram->pcd =
97450ee11fe383255db8e5c3307319d470015616f27Bob Beers        __constant_cpu_to_le32 ((e1mode ? 1 : 0) |
97550ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_PCD_TXSYNC_RISING |
97650ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_PCD_RXSYNC_RISING |
97750ee11fe383255db8e5c3307319d470015616f27Bob Beers                                MUSYCC_PCD_RXDATA_RISING);
97850ee11fe383255db8e5c3307319d470015616f27Bob Beers
97950ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* Message length descriptor */
980c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beers       pi->regram->mld = __constant_cpu_to_le32 (cxt1e1_max_mru | (cxt1e1_max_mru << 16));
98150ee11fe383255db8e5c3307319d470015616f27Bob Beers
98250ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* tsm algorithm */
98350ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0; i < 32; i++)
98450ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
98550ee11fe383255db8e5c3307319d470015616f27Bob Beers
98650ee11fe383255db8e5c3307319d470015616f27Bob Beers        /*** ASSIGNMENT NOTES:                             ***/
98750ee11fe383255db8e5c3307319d470015616f27Bob Beers        /*** Group's channel  ZERO  unavailable if E1.     ***/
98850ee11fe383255db8e5c3307319d470015616f27Bob Beers        /*** Group's channel  16    unavailable if E1 CAS. ***/
98950ee11fe383255db8e5c3307319d470015616f27Bob Beers        /*** Group's channels 24-31 unavailable if T1.     ***/
99050ee11fe383255db8e5c3307319d470015616f27Bob Beers
99150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (((i == 0) && e1mode) ||
99250ee11fe383255db8e5c3307319d470015616f27Bob Beers            ((i == 16) && ((pp->port_mode == CFG_FRAME_E1CRC_CAS) || (pp->port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
99350ee11fe383255db8e5c3307319d470015616f27Bob Beers            || ((i > 23) && (!e1mode)))
99450ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
99550ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->tsm[i] = 0xff;      /* make tslot unavailable for this mode */
99650ee11fe383255db8e5c3307319d470015616f27Bob Beers        } else
99750ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
99850ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->tsm[i] = 0x00;      /* make tslot available for assignment */
99950ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
100050ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
100150ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0; i < MUSYCC_NCHANS; i++)
100250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
100350ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->regram->ttsm[i] = 0;
100450ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->regram->rtsm[i] = 0;
100550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
100650ee11fe383255db8e5c3307319d470015616f27Bob Beers    FLUSH_MEM_WRITE ();
100750ee11fe383255db8e5c3307319d470015616f27Bob Beers    musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION);
100850ee11fe383255db8e5c3307319d470015616f27Bob Beers    musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION);
100950ee11fe383255db8e5c3307319d470015616f27Bob Beers
101050ee11fe383255db8e5c3307319d470015616f27Bob Beers    musycc_init_mdt (pi);
101150ee11fe383255db8e5c3307319d470015616f27Bob Beers
101250ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->group_is_set = 1;
101350ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->p = *pp;
101450ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
101550ee11fe383255db8e5c3307319d470015616f27Bob Beers}
101650ee11fe383255db8e5c3307319d470015616f27Bob Beers
101750ee11fe383255db8e5c3307319d470015616f27Bob Beers
101850ee11fe383255db8e5c3307319d470015616f27Bob Beersunsigned int max_int = 0;
101950ee11fe383255db8e5c3307319d470015616f27Bob Beers
102050ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
102150ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_new_chan (ci_t * ci, int portnum, int channum, void *user)
102250ee11fe383255db8e5c3307319d470015616f27Bob Beers{
102350ee11fe383255db8e5c3307319d470015616f27Bob Beers    mpi_t      *pi;
102450ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
102550ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         gchan;
102650ee11fe383255db8e5c3307319d470015616f27Bob Beers
102750ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (c4_find_chan (channum))     /* a new channel shouldn't already exist */
102850ee11fe383255db8e5c3307319d470015616f27Bob Beers        return EEXIST;
102950ee11fe383255db8e5c3307319d470015616f27Bob Beers
103050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (portnum >= ci->max_port)    /* sanity check */
103150ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENXIO;
103250ee11fe383255db8e5c3307319d470015616f27Bob Beers
103350ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi = &(ci->port[portnum]);
103450ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* find any available channel within this port */
103550ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
103650ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
103750ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch = pi->chan[gchan];
103850ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ch && ch->state == UNASSIGNED)      /* no assignment is good! */
103950ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
104050ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
104150ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (gchan == MUSYCC_NCHANS)     /* exhausted table, all were assigned */
104250ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENFILE;
104350ee11fe383255db8e5c3307319d470015616f27Bob Beers
104450ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->up = pi;
104550ee11fe383255db8e5c3307319d470015616f27Bob Beers
104650ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* NOTE: mch_t already cleared during OS_kmalloc() */
104750ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->state = DOWN;
104850ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->user = user;
104950ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->gchan = gchan;
105050ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->channum = channum;          /* mark our channel assignment */
105150ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.channum = channum;
105250ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 1
105350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.card = ci->brdno;
105450ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.port = portnum;
105550ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
105650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16;
105750ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.idlecode = CFG_CH_FLAG_7E;
105850ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.pad_fill_count = 2;
105950ee11fe383255db8e5c3307319d470015616f27Bob Beers    spin_lock_init (&ch->ch_rxlock);
106050ee11fe383255db8e5c3307319d470015616f27Bob Beers    spin_lock_init (&ch->ch_txlock);
106150ee11fe383255db8e5c3307319d470015616f27Bob Beers
106250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
106350ee11fe383255db8e5c3307319d470015616f27Bob Beers        status_t    ret;
106450ee11fe383255db8e5c3307319d470015616f27Bob Beers
106550ee11fe383255db8e5c3307319d470015616f27Bob Beers        if ((ret = c4_wk_chan_init (pi, ch)))
106650ee11fe383255db8e5c3307319d470015616f27Bob Beers            return ret;
106750ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
106850ee11fe383255db8e5c3307319d470015616f27Bob Beers
106950ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* save off interface assignments which bound a board */
107050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ci->first_if == 0)          /* first channel registered is assumed to
107150ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * be the lowest channel */
107250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
107350ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->first_if = ci->last_if = user;
107450ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->first_channum = ci->last_channum = channum;
107550ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
107650ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
107750ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci->last_if = user;
107850ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ci->last_channum < channum) /* higher number channel found */
107950ee11fe383255db8e5c3307319d470015616f27Bob Beers            ci->last_channum = channum;
108050ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
108150ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
108250ee11fe383255db8e5c3307319d470015616f27Bob Beers}
108350ee11fe383255db8e5c3307319d470015616f27Bob Beers
108450ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
108550ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_del_chan (int channum)
108650ee11fe383255db8e5c3307319d470015616f27Bob Beers{
108750ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
108850ee11fe383255db8e5c3307319d470015616f27Bob Beers
108950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch = c4_find_chan (channum)))
109050ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
109150ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->state == UP)
109250ee11fe383255db8e5c3307319d470015616f27Bob Beers        musycc_chan_down ((ci_t *) 0, channum);
109350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->state = UNASSIGNED;
109450ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->gchan = (-1);
109550ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->channum = (-1);
109650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p.channum = (-1);
109750ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
109850ee11fe383255db8e5c3307319d470015616f27Bob Beers}
109950ee11fe383255db8e5c3307319d470015616f27Bob Beers
110050ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
110150ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_del_chan_stats (int channum)
110250ee11fe383255db8e5c3307319d470015616f27Bob Beers{
110350ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
110450ee11fe383255db8e5c3307319d470015616f27Bob Beers
110550ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch = c4_find_chan (channum)))
110650ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
110750ee11fe383255db8e5c3307319d470015616f27Bob Beers
110850ee11fe383255db8e5c3307319d470015616f27Bob Beers    memset (&ch->s, 0, sizeof (struct sbecom_chan_stats));
110950ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
111050ee11fe383255db8e5c3307319d470015616f27Bob Beers}
111150ee11fe383255db8e5c3307319d470015616f27Bob Beers
111250ee11fe383255db8e5c3307319d470015616f27Bob Beers
111350ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
111450ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_set_chan (int channum, struct sbecom_chan_param * p)
111550ee11fe383255db8e5c3307319d470015616f27Bob Beers{
111650ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
111750ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         i, x = 0;
111850ee11fe383255db8e5c3307319d470015616f27Bob Beers
111950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch = c4_find_chan (channum)))
112050ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
112150ee11fe383255db8e5c3307319d470015616f27Bob Beers
112250ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 1
112350ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->p.card != p->card ||
112450ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch->p.port != p->port ||
112550ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch->p.channum != p->channum)
112650ee11fe383255db8e5c3307319d470015616f27Bob Beers        return EINVAL;
112750ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
112850ee11fe383255db8e5c3307319d470015616f27Bob Beers
112950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch->up->group_is_set))
113050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
113150ee11fe383255db8e5c3307319d470015616f27Bob Beers        return EIO;                 /* out of order, SET_PORT command
113250ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * required prior to first group's
113350ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * SET_CHAN command */
113450ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
113550ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*
113650ee11fe383255db8e5c3307319d470015616f27Bob Beers     * Check for change of parameter settings in order to invoke closing of
113750ee11fe383255db8e5c3307319d470015616f27Bob Beers     * channel prior to hardware poking.
113850ee11fe383255db8e5c3307319d470015616f27Bob Beers     */
113950ee11fe383255db8e5c3307319d470015616f27Bob Beers
114050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->p.status != p->status || ch->p.chan_mode != p->chan_mode ||
114150ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch->p.data_inv != p->data_inv || ch->p.intr_mask != p->intr_mask ||
114250ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch->txd_free < ch->txd_num) /* to clear out queued messages */
114350ee11fe383255db8e5c3307319d470015616f27Bob Beers        x = 1;                      /* we have a change requested */
114450ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0; i < 32; i++)        /* check for timeslot mapping changes */
114550ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ch->p.bitmask[i] != p->bitmask[i])
114650ee11fe383255db8e5c3307319d470015616f27Bob Beers            x = 1;                  /* we have a change requested */
114750ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->p = *p;
114850ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (x && (ch->state == UP))     /* if change request and channel is
114950ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * open... */
115050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
115150ee11fe383255db8e5c3307319d470015616f27Bob Beers        status_t    ret;
115250ee11fe383255db8e5c3307319d470015616f27Bob Beers
115350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if ((ret = musycc_chan_down ((ci_t *) 0, channum)))
115450ee11fe383255db8e5c3307319d470015616f27Bob Beers            return ret;
115550ee11fe383255db8e5c3307319d470015616f27Bob Beers        if ((ret = c4_chan_up (ch->up->up, channum)))
115650ee11fe383255db8e5c3307319d470015616f27Bob Beers            return ret;
115750ee11fe383255db8e5c3307319d470015616f27Bob Beers        sd_enable_xmit (ch->user);  /* re-enable to catch flow controlled
115850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * channel */
115950ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
116050ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
116150ee11fe383255db8e5c3307319d470015616f27Bob Beers}
116250ee11fe383255db8e5c3307319d470015616f27Bob Beers
116350ee11fe383255db8e5c3307319d470015616f27Bob Beers
116450ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
116550ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_get_chan (int channum, struct sbecom_chan_param * p)
116650ee11fe383255db8e5c3307319d470015616f27Bob Beers{
116750ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
116850ee11fe383255db8e5c3307319d470015616f27Bob Beers
116950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch = c4_find_chan (channum)))
117050ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
117150ee11fe383255db8e5c3307319d470015616f27Bob Beers    *p = ch->p;
117250ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
117350ee11fe383255db8e5c3307319d470015616f27Bob Beers}
117450ee11fe383255db8e5c3307319d470015616f27Bob Beers
117550ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
117650ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_get_chan_stats (int channum, struct sbecom_chan_stats * p)
117750ee11fe383255db8e5c3307319d470015616f27Bob Beers{
117850ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
117950ee11fe383255db8e5c3307319d470015616f27Bob Beers
118050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch = c4_find_chan (channum)))
118150ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
118250ee11fe383255db8e5c3307319d470015616f27Bob Beers    *p = ch->s;
118350ee11fe383255db8e5c3307319d470015616f27Bob Beers    p->tx_pending = atomic_read (&ch->tx_pending);
118450ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
118550ee11fe383255db8e5c3307319d470015616f27Bob Beers}
118650ee11fe383255db8e5c3307319d470015616f27Bob Beers
118750ee11fe383255db8e5c3307319d470015616f27Bob BeersSTATIC int
118850ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_fifo_alloc (mpi_t * pi, int chan, int *len)
118950ee11fe383255db8e5c3307319d470015616f27Bob Beers{
119050ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         i, l = 0, start = 0, max = 0, maxstart = 0;
119150ee11fe383255db8e5c3307319d470015616f27Bob Beers
119250ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0; i < 32; i++)
119350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
119450ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (pi->fifomap[i] != -1)
119550ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
119650ee11fe383255db8e5c3307319d470015616f27Bob Beers            l = 0;
119750ee11fe383255db8e5c3307319d470015616f27Bob Beers            start = i + 1;
119850ee11fe383255db8e5c3307319d470015616f27Bob Beers            continue;
119950ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
120050ee11fe383255db8e5c3307319d470015616f27Bob Beers        ++l;
120150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (l > max)
120250ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
120350ee11fe383255db8e5c3307319d470015616f27Bob Beers            max = l;
120450ee11fe383255db8e5c3307319d470015616f27Bob Beers            maxstart = start;
120550ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
120650ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (max == *len)
120750ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
120850ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
120950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (max != *len)
121050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
1211b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        if (cxt1e1_log_level >= LOG_WARN)
1212694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("%s: wanted to allocate %d fifo space, but got only %d\n",
121350ee11fe383255db8e5c3307319d470015616f27Bob Beers                    pi->up->devname, *len, max);
121450ee11fe383255db8e5c3307319d470015616f27Bob Beers        *len = max;
121550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
1216b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman    if (cxt1e1_log_level >= LOG_DEBUG)
1217694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("%s: allocated %d fifo at %d for channel %d/%d\n",
121850ee11fe383255db8e5c3307319d470015616f27Bob Beers                pi->up->devname, max, start, chan, pi->p.portnum);
121950ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = maxstart; i < (maxstart + max); i++)
122050ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->fifomap[i] = chan;
122150ee11fe383255db8e5c3307319d470015616f27Bob Beers    return start;
122250ee11fe383255db8e5c3307319d470015616f27Bob Beers}
122350ee11fe383255db8e5c3307319d470015616f27Bob Beers
122450ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
122550ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_fifo_free (mpi_t * pi, int chan)
122650ee11fe383255db8e5c3307319d470015616f27Bob Beers{
122750ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         i;
122850ee11fe383255db8e5c3307319d470015616f27Bob Beers
1229b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman    if (cxt1e1_log_level >= LOG_DEBUG)
1230694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("%s: deallocated fifo for channel %d/%d\n",
123150ee11fe383255db8e5c3307319d470015616f27Bob Beers                pi->up->devname, chan, pi->p.portnum);
123250ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0; i < 32; i++)
123350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (pi->fifomap[i] == chan)
123450ee11fe383255db8e5c3307319d470015616f27Bob Beers            pi->fifomap[i] = -1;
123550ee11fe383255db8e5c3307319d470015616f27Bob Beers}
123650ee11fe383255db8e5c3307319d470015616f27Bob Beers
123750ee11fe383255db8e5c3307319d470015616f27Bob Beers
123850ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
123950ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_chan_up (ci_t * ci, int channum)
124050ee11fe383255db8e5c3307319d470015616f27Bob Beers{
124150ee11fe383255db8e5c3307319d470015616f27Bob Beers    mpi_t      *pi;
124250ee11fe383255db8e5c3307319d470015616f27Bob Beers    mch_t      *ch;
124350ee11fe383255db8e5c3307319d470015616f27Bob Beers    struct mbuf *m;
124450ee11fe383255db8e5c3307319d470015616f27Bob Beers    struct mdesc *md;
124550ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         nts, nbuf, txnum, rxnum;
124650ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         addr, i, j, gchan;
124750ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int32_t   tmp;            /* for optimizing conversion across BE
124850ee11fe383255db8e5c3307319d470015616f27Bob Beers                                 * platform */
124950ee11fe383255db8e5c3307319d470015616f27Bob Beers
125050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(ch = c4_find_chan (channum)))
125150ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
125250ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->state == UP)
125350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
1254b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        if (cxt1e1_log_level >= LOG_MONITOR)
1255694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches            pr_info("%s: channel already UP, graceful early exit\n",
1256694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                    ci->devname);
125750ee11fe383255db8e5c3307319d470015616f27Bob Beers        return 0;
125850ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
125950ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi = ch->up;
126050ee11fe383255db8e5c3307319d470015616f27Bob Beers    gchan = ch->gchan;
126150ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* find nts ('number of timeslots') */
126250ee11fe383255db8e5c3307319d470015616f27Bob Beers    nts = 0;
126350ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0; i < 32; i++)
126450ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
126550ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ch->p.bitmask[i] & pi->tsm[i])
126650ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
1267b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            if (1 || cxt1e1_log_level >= LOG_WARN)
126850ee11fe383255db8e5c3307319d470015616f27Bob Beers            {
1269694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                pr_info("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n",
127050ee11fe383255db8e5c3307319d470015616f27Bob Beers                        ci->devname, channum, i);
1271694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                pr_info("+ ask4 %x, currently %x\n",
1272694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                        ch->p.bitmask[i], pi->tsm[i]);
127350ee11fe383255db8e5c3307319d470015616f27Bob Beers            }
127450ee11fe383255db8e5c3307319d470015616f27Bob Beers            return EINVAL;
127550ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
127650ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (j = 0; j < 8; j++)
127750ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (ch->p.bitmask[i] & (1 << j))
127850ee11fe383255db8e5c3307319d470015616f27Bob Beers                nts++;
127950ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
128050ee11fe383255db8e5c3307319d470015616f27Bob Beers
128150ee11fe383255db8e5c3307319d470015616f27Bob Beers    nbuf = nts / 8 ? nts / 8 : 1;
128250ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!nbuf)
128350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
1284b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman        /* if( cxt1e1_log_level >= LOG_WARN)  */
1285694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n",
1286694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                ci->devname, channum);
128750ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOBUFS;             /* this should not happen */
128850ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
128950ee11fe383255db8e5c3307319d470015616f27Bob Beers    addr = c4_fifo_alloc (pi, gchan, &nbuf);
129050ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->state = UP;
129150ee11fe383255db8e5c3307319d470015616f27Bob Beers
129250ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* Setup the Time Slot Map */
129350ee11fe383255db8e5c3307319d470015616f27Bob Beers    musycc_update_timeslots (pi);
129450ee11fe383255db8e5c3307319d470015616f27Bob Beers
129550ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* ch->tx_limit = nts; */
129650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->s.tx_pending = 0;
129750ee11fe383255db8e5c3307319d470015616f27Bob Beers
129850ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* Set Channel Configuration Descriptors */
129950ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
130050ee11fe383255db8e5c3307319d470015616f27Bob Beers        u_int32_t   ccd;
130150ee11fe383255db8e5c3307319d470015616f27Bob Beers
130250ee11fe383255db8e5c3307319d470015616f27Bob Beers        ccd = musycc_chan_proto (ch->p.chan_mode) << MUSYCC_CCD_PROTO_SHIFT;
130350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if ((ch->p.chan_mode == CFG_CH_PROTO_ISLP_MODE) ||
130450ee11fe383255db8e5c3307319d470015616f27Bob Beers            (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
130550ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
130650ee11fe383255db8e5c3307319d470015616f27Bob Beers            ccd |= MUSYCC_CCD_FCS_XFER; /* Non FSC Mode */
130750ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
130850ee11fe383255db8e5c3307319d470015616f27Bob Beers        ccd |= 2 << MUSYCC_CCD_MAX_LENGTH;      /* Select second MTU */
130950ee11fe383255db8e5c3307319d470015616f27Bob Beers        ccd |= ch->p.intr_mask;
131050ee11fe383255db8e5c3307319d470015616f27Bob Beers        ccd |= addr << MUSYCC_CCD_BUFFER_LOC;
131150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
131250ee11fe383255db8e5c3307319d470015616f27Bob Beers            ccd |= (nbuf) << MUSYCC_CCD_BUFFER_LENGTH;
131350ee11fe383255db8e5c3307319d470015616f27Bob Beers        else
131450ee11fe383255db8e5c3307319d470015616f27Bob Beers            ccd |= (nbuf - 1) << MUSYCC_CCD_BUFFER_LENGTH;
131550ee11fe383255db8e5c3307319d470015616f27Bob Beers
131650ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ch->p.data_inv & CFG_CH_DINV_TX)
131750ee11fe383255db8e5c3307319d470015616f27Bob Beers            ccd |= MUSYCC_CCD_INVERT_DATA;      /* Invert data */
131850ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->regram->tcct[gchan] = cpu_to_le32 (ccd);
131950ee11fe383255db8e5c3307319d470015616f27Bob Beers
132050ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ch->p.data_inv & CFG_CH_DINV_RX)
132150ee11fe383255db8e5c3307319d470015616f27Bob Beers            ccd |= MUSYCC_CCD_INVERT_DATA;      /* Invert data */
132250ee11fe383255db8e5c3307319d470015616f27Bob Beers        else
132350ee11fe383255db8e5c3307319d470015616f27Bob Beers            ccd &= ~MUSYCC_CCD_INVERT_DATA;     /* take away data inversion */
132450ee11fe383255db8e5c3307319d470015616f27Bob Beers        pi->regram->rcct[gchan] = cpu_to_le32 (ccd);
132550ee11fe383255db8e5c3307319d470015616f27Bob Beers        FLUSH_MEM_WRITE ();
132650ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
132750ee11fe383255db8e5c3307319d470015616f27Bob Beers
132850ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* Reread the Channel Configuration Descriptor for this channel */
132950ee11fe383255db8e5c3307319d470015616f27Bob Beers    musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_RX_DIRECTION | gchan);
133050ee11fe383255db8e5c3307319d470015616f27Bob Beers    musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_TX_DIRECTION | gchan);
133150ee11fe383255db8e5c3307319d470015616f27Bob Beers
133250ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*
133350ee11fe383255db8e5c3307319d470015616f27Bob Beers     * Figure out how many buffers we want.  If the customer has changed from
133450ee11fe383255db8e5c3307319d470015616f27Bob Beers     * the defaults, then use the changed values.  Otherwise, use Transparent
133550ee11fe383255db8e5c3307319d470015616f27Bob Beers     * mode's specific minimum default settings.
133650ee11fe383255db8e5c3307319d470015616f27Bob Beers     */
133750ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
133850ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
133950ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (max_rxdesc_used == max_rxdesc_default)      /* use default setting */
134050ee11fe383255db8e5c3307319d470015616f27Bob Beers            max_rxdesc_used = MUSYCC_RXDESC_TRANS;
134150ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (max_txdesc_used == max_txdesc_default)      /* use default setting */
134250ee11fe383255db8e5c3307319d470015616f27Bob Beers            max_txdesc_used = MUSYCC_TXDESC_TRANS;
134350ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
134450ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*
134550ee11fe383255db8e5c3307319d470015616f27Bob Beers     * Increase counts when hyperchanneling, since this implies an increase
134650ee11fe383255db8e5c3307319d470015616f27Bob Beers     * in throughput per channel
134750ee11fe383255db8e5c3307319d470015616f27Bob Beers     */
134850ee11fe383255db8e5c3307319d470015616f27Bob Beers    rxnum = max_rxdesc_used + (nts / 4);
134950ee11fe383255db8e5c3307319d470015616f27Bob Beers    txnum = max_txdesc_used + (nts / 4);
135050ee11fe383255db8e5c3307319d470015616f27Bob Beers
135150ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 0
135250ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* DEBUG INFO */
1353b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman    if (cxt1e1_log_level >= LOG_MONITOR)
1354694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n",
135550ee11fe383255db8e5c3307319d470015616f27Bob Beers                ci->devname, ch->p.chan_mode,
135650ee11fe383255db8e5c3307319d470015616f27Bob Beers                rxnum, max_rxdesc_used, max_rxdesc_default,
135750ee11fe383255db8e5c3307319d470015616f27Bob Beers                txnum, max_txdesc_used, max_txdesc_default);
135850ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
135950ee11fe383255db8e5c3307319d470015616f27Bob Beers
136050ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->rxd_num = rxnum;
136150ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->txd_num = txnum;
136250ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->rxix_irq_srv = 0;
136350ee11fe383255db8e5c3307319d470015616f27Bob Beers
136450ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->mdr = OS_kmalloc (sizeof (struct mdesc) * rxnum);
136550ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->mdt = OS_kmalloc (sizeof (struct mdesc) * txnum);
136650ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
1367c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beers               tmp = __constant_cpu_to_le32 (cxt1e1_max_mru | EOBIRQ_ENABLE);
136850ee11fe383255db8e5c3307319d470015616f27Bob Beers    else
1369c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beers               tmp = __constant_cpu_to_le32 (cxt1e1_max_mru);
137050ee11fe383255db8e5c3307319d470015616f27Bob Beers
137150ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0, md = ch->mdr; i < rxnum; i++, md++)
137250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
137350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (i == (rxnum - 1))
137450ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
137550ee11fe383255db8e5c3307319d470015616f27Bob Beers            md->snext = &ch->mdr[0];/* wrapness */
137650ee11fe383255db8e5c3307319d470015616f27Bob Beers        } else
137750ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
137850ee11fe383255db8e5c3307319d470015616f27Bob Beers            md->snext = &ch->mdr[i + 1];
137950ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
138050ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->next = cpu_to_le32 (OS_vtophys (md->snext));
138150ee11fe383255db8e5c3307319d470015616f27Bob Beers
1382c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beers               if (!(m = OS_mem_token_alloc (cxt1e1_max_mru)))
138350ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
1384b8b739941eb57ec4c5fc87a73e7e7b554cf395fbGreg Kroah-Hartman            if (cxt1e1_log_level >= LOG_MONITOR)
1385694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches                pr_info("%s: c4_chan_up[%d] - token alloc failure, size = %d.\n",
1386c694ed85eab4e7966cd83fca509ce27494e3e296Bob Beers                                               ci->devname, channum, cxt1e1_max_mru);
138750ee11fe383255db8e5c3307319d470015616f27Bob Beers            goto errfree;
138850ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
138950ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->mem_token = m;
139050ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m)));
139150ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->status = tmp | MUSYCC_RX_OWNED;     /* MUSYCC owns RX descriptor **
139250ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * CODING NOTE:
139350ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * MUSYCC_RX_OWNED = 0 so no
139450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * need to byteSwap */
139550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
139650ee11fe383255db8e5c3307319d470015616f27Bob Beers
139750ee11fe383255db8e5c3307319d470015616f27Bob Beers    for (i = 0, md = ch->mdt; i < txnum; i++, md++)
139850ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
139950ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING
140050ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * NOTE: HOST_TX_OWNED = 0 so no need to
140150ee11fe383255db8e5c3307319d470015616f27Bob Beers                                     * byteSwap */
140250ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->mem_token = 0;
140350ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->data = 0;
140450ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (i == (txnum - 1))
140550ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
140650ee11fe383255db8e5c3307319d470015616f27Bob Beers            md->snext = &ch->mdt[0];/* wrapness */
140750ee11fe383255db8e5c3307319d470015616f27Bob Beers        } else
140850ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
140950ee11fe383255db8e5c3307319d470015616f27Bob Beers            md->snext = &ch->mdt[i + 1];
141050ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
141150ee11fe383255db8e5c3307319d470015616f27Bob Beers        md->next = cpu_to_le32 (OS_vtophys (md->snext));
141250ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
141350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->txd_irq_srv = ch->txd_usr_add = &ch->mdt[0];
141450ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->txd_free = txnum;
141550ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->tx_full = 0;
141650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->txd_required = 0;
141750ee11fe383255db8e5c3307319d470015616f27Bob Beers
141850ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* Configure it into the chip */
141950ee11fe383255db8e5c3307319d470015616f27Bob Beers    tmp = cpu_to_le32 (OS_vtophys (&ch->mdt[0]));
142050ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->regram->thp[gchan] = tmp;
142150ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->regram->tmp[gchan] = tmp;
142250ee11fe383255db8e5c3307319d470015616f27Bob Beers
142350ee11fe383255db8e5c3307319d470015616f27Bob Beers    tmp = cpu_to_le32 (OS_vtophys (&ch->mdr[0]));
142450ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->regram->rhp[gchan] = tmp;
142550ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->regram->rmp[gchan] = tmp;
142650ee11fe383255db8e5c3307319d470015616f27Bob Beers
142750ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* Activate the Channel */
142850ee11fe383255db8e5c3307319d470015616f27Bob Beers    FLUSH_MEM_WRITE ();
142950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->p.status & RX_ENABLED)
143050ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
143150ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef RLD_TRANS_DEBUG
1432694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum);
143350ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
143450ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch->ch_start_rx = 0;        /* we are restarting RX... */
143550ee11fe383255db8e5c3307319d470015616f27Bob Beers        musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan);
143650ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
143750ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ch->p.status & TX_ENABLED)
143850ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
143950ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef RLD_TRANS_DEBUG
1440694a98073f83ce1c14e3c0bba182bfeba5c44f01Joe Perches        pr_info("++ c4_chan_up() CHAN TX ACTIVATE: chan %d <delayed>\n", ch->channum);
144150ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
144250ee11fe383255db8e5c3307319d470015616f27Bob Beers        ch->ch_start_tx = CH_START_TX_1ST;      /* we are delaying start
144350ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * until receipt from user of
144450ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * first packet to transmit. */
144550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
144650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->status = ch->p.status;
144750ee11fe383255db8e5c3307319d470015616f27Bob Beers    pi->openchans++;
144850ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
144950ee11fe383255db8e5c3307319d470015616f27Bob Beers
145050ee11fe383255db8e5c3307319d470015616f27Bob Beerserrfree:
145150ee11fe383255db8e5c3307319d470015616f27Bob Beers    while (i > 0)
145250ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
145350ee11fe383255db8e5c3307319d470015616f27Bob Beers        /* Don't leak all the previously allocated mbufs in this loop */
145450ee11fe383255db8e5c3307319d470015616f27Bob Beers        i--;
145550ee11fe383255db8e5c3307319d470015616f27Bob Beers        OS_mem_token_free (ch->mdr[i].mem_token);
145650ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
145750ee11fe383255db8e5c3307319d470015616f27Bob Beers    OS_kfree (ch->mdt);
145850ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->mdt = 0;
145950ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->txd_num = 0;
146050ee11fe383255db8e5c3307319d470015616f27Bob Beers    OS_kfree (ch->mdr);
146150ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->mdr = 0;
146250ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->rxd_num = 0;
146350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ch->state = DOWN;
146450ee11fe383255db8e5c3307319d470015616f27Bob Beers    return ENOBUFS;
146550ee11fe383255db8e5c3307319d470015616f27Bob Beers}
146650ee11fe383255db8e5c3307319d470015616f27Bob Beers
146750ee11fe383255db8e5c3307319d470015616f27Bob Beers/* stop the hardware from servicing & interrupting */
146850ee11fe383255db8e5c3307319d470015616f27Bob Beers
146950ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
147050ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_stopwd (ci_t * ci)
147150ee11fe383255db8e5c3307319d470015616f27Bob Beers{
147250ee11fe383255db8e5c3307319d470015616f27Bob Beers    OS_stop_watchdog (&ci->wd);
147350ee11fe383255db8e5c3307319d470015616f27Bob Beers    SD_SEM_TAKE (&ci->sem_wdbusy, "_stop_");    /* ensure WD not running */
147450ee11fe383255db8e5c3307319d470015616f27Bob Beers    SD_SEM_GIVE (&ci->sem_wdbusy);
147550ee11fe383255db8e5c3307319d470015616f27Bob Beers}
147650ee11fe383255db8e5c3307319d470015616f27Bob Beers
147750ee11fe383255db8e5c3307319d470015616f27Bob Beers
147850ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
147950ee11fe383255db8e5c3307319d470015616f27Bob Beerssbecom_get_brdinfo (ci_t * ci, struct sbe_brd_info * bip, u_int8_t *bsn)
148050ee11fe383255db8e5c3307319d470015616f27Bob Beers{
148150ee11fe383255db8e5c3307319d470015616f27Bob Beers    char       *np;
148250ee11fe383255db8e5c3307319d470015616f27Bob Beers    u_int32_t   sn = 0;
148350ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         i;
148450ee11fe383255db8e5c3307319d470015616f27Bob Beers
148550ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brdno = ci->brdno;         /* our board number */
148650ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brd_id = ci->brd_id;
148750ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brd_hdw_id = ci->hdw_bid;
148850ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brd_chan_cnt = MUSYCC_NCHANS * ci->max_port;   /* number of channels
148950ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                         * being used */
149050ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brd_port_cnt = ci->max_port;   /* number of ports being used */
149150ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brd_pci_speed = BINFO_PCI_SPEED_unk;   /* PCI speed not yet
149250ee11fe383255db8e5c3307319d470015616f27Bob Beers                                                 * determinable */
149350ee11fe383255db8e5c3307319d470015616f27Bob Beers
149450ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ci->first_if)
149550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
149650ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
149750ee11fe383255db8e5c3307319d470015616f27Bob Beers            struct net_device *dev;
149850ee11fe383255db8e5c3307319d470015616f27Bob Beers
149950ee11fe383255db8e5c3307319d470015616f27Bob Beers            dev = (struct net_device *) ci->first_if;
150050ee11fe383255db8e5c3307319d470015616f27Bob Beers            np = (char *) dev->name;
150150ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
150250ee11fe383255db8e5c3307319d470015616f27Bob Beers        strncpy (bip->first_iname, np, CHNM_STRLEN - 1);
150350ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
150450ee11fe383255db8e5c3307319d470015616f27Bob Beers        strcpy (bip->first_iname, "<NULL>");
150550ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ci->last_if)
150650ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
150750ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
150850ee11fe383255db8e5c3307319d470015616f27Bob Beers            struct net_device *dev;
150950ee11fe383255db8e5c3307319d470015616f27Bob Beers
151050ee11fe383255db8e5c3307319d470015616f27Bob Beers            dev = (struct net_device *) ci->last_if;
151150ee11fe383255db8e5c3307319d470015616f27Bob Beers            np = (char *) dev->name;
151250ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
151350ee11fe383255db8e5c3307319d470015616f27Bob Beers        strncpy (bip->last_iname, np, CHNM_STRLEN - 1);
151450ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
151550ee11fe383255db8e5c3307319d470015616f27Bob Beers        strcpy (bip->last_iname, "<NULL>");
151650ee11fe383255db8e5c3307319d470015616f27Bob Beers
151750ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (bsn)
151850ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
151950ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (i = 0; i < 3; i++)
152050ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
152150ee11fe383255db8e5c3307319d470015616f27Bob Beers            bip->brd_mac_addr[i] = *bsn++;
152250ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
152350ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (; i < 6; i++)
152450ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
152550ee11fe383255db8e5c3307319d470015616f27Bob Beers            bip->brd_mac_addr[i] = *bsn;
152650ee11fe383255db8e5c3307319d470015616f27Bob Beers            sn = (sn << 8) | *bsn++;
152750ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
152850ee11fe383255db8e5c3307319d470015616f27Bob Beers    } else
152950ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
153050ee11fe383255db8e5c3307319d470015616f27Bob Beers        for (i = 0; i < 6; i++)
153150ee11fe383255db8e5c3307319d470015616f27Bob Beers            bip->brd_mac_addr[i] = 0;
153250ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
153350ee11fe383255db8e5c3307319d470015616f27Bob Beers    bip->brd_sn = sn;
153450ee11fe383255db8e5c3307319d470015616f27Bob Beers}
153550ee11fe383255db8e5c3307319d470015616f27Bob Beers
153650ee11fe383255db8e5c3307319d470015616f27Bob Beers
153750ee11fe383255db8e5c3307319d470015616f27Bob Beersstatus_t
153850ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip)
153950ee11fe383255db8e5c3307319d470015616f27Bob Beers{
154050ee11fe383255db8e5c3307319d470015616f27Bob Beers    struct net_device *dev;
154150ee11fe383255db8e5c3307319d470015616f27Bob Beers    char       *np;
154250ee11fe383255db8e5c3307319d470015616f27Bob Beers
154350ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (!(dev = getuserbychan (iip->channum)))
154450ee11fe383255db8e5c3307319d470015616f27Bob Beers        return ENOENT;
154550ee11fe383255db8e5c3307319d470015616f27Bob Beers
154650ee11fe383255db8e5c3307319d470015616f27Bob Beers    np = dev->name;
154750ee11fe383255db8e5c3307319d470015616f27Bob Beers    strncpy (iip->iname, np, CHNM_STRLEN - 1);
154850ee11fe383255db8e5c3307319d470015616f27Bob Beers    return 0;
154950ee11fe383255db8e5c3307319d470015616f27Bob Beers}
155050ee11fe383255db8e5c3307319d470015616f27Bob Beers
155150ee11fe383255db8e5c3307319d470015616f27Bob Beers
155250ee11fe383255db8e5c3307319d470015616f27Bob Beers#ifdef CONFIG_SBE_PMCC4_NCOMM
155350ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid        (*nciInterrupt[MAX_BOARDS][4]) (void);
155450ee11fe383255db8e5c3307319d470015616f27Bob Beersextern void wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler);
155550ee11fe383255db8e5c3307319d470015616f27Bob Beers
155650ee11fe383255db8e5c3307319d470015616f27Bob Beersvoid
155750ee11fe383255db8e5c3307319d470015616f27Bob BeerswanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler)
155850ee11fe383255db8e5c3307319d470015616f27Bob Beers{
155950ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (cardID < MAX_BOARDS)    /* sanity check */
156050ee11fe383255db8e5c3307319d470015616f27Bob Beers        nciInterrupt[cardID][deviceID] = handler;
156150ee11fe383255db8e5c3307319d470015616f27Bob Beers}
156250ee11fe383255db8e5c3307319d470015616f27Bob Beers
156350ee11fe383255db8e5c3307319d470015616f27Bob Beersirqreturn_t
156450ee11fe383255db8e5c3307319d470015616f27Bob Beersc4_ebus_intr_th_handler (void *devp)
156550ee11fe383255db8e5c3307319d470015616f27Bob Beers{
156650ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci_t       *ci = (ci_t *) devp;
156750ee11fe383255db8e5c3307319d470015616f27Bob Beers    volatile u_int32_t ists;
156850ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         handled = 0;
156950ee11fe383255db8e5c3307319d470015616f27Bob Beers    int         brdno;
157050ee11fe383255db8e5c3307319d470015616f27Bob Beers
157150ee11fe383255db8e5c3307319d470015616f27Bob Beers    /* which COMET caused the interrupt */
157250ee11fe383255db8e5c3307319d470015616f27Bob Beers    brdno = ci->brdno;
157350ee11fe383255db8e5c3307319d470015616f27Bob Beers    ists = pci_read_32 ((u_int32_t *) &ci->cpldbase->intr);
157450ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ists & PMCC4_CPLD_INTR_CMT_1)
157550ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
157650ee11fe383255db8e5c3307319d470015616f27Bob Beers        handled = 0x1;
157750ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (nciInterrupt[brdno][0] != NULL)
157850ee11fe383255db8e5c3307319d470015616f27Bob Beers            (*nciInterrupt[brdno][0]) ();
157950ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
158050ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ists & PMCC4_CPLD_INTR_CMT_2)
158150ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
158250ee11fe383255db8e5c3307319d470015616f27Bob Beers        handled |= 0x2;
158350ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (nciInterrupt[brdno][1] != NULL)
158450ee11fe383255db8e5c3307319d470015616f27Bob Beers            (*nciInterrupt[brdno][1]) ();
158550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
158650ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ists & PMCC4_CPLD_INTR_CMT_3)
158750ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
158850ee11fe383255db8e5c3307319d470015616f27Bob Beers        handled |= 0x4;
158950ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (nciInterrupt[brdno][2] != NULL)
159050ee11fe383255db8e5c3307319d470015616f27Bob Beers            (*nciInterrupt[brdno][2]) ();
159150ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
159250ee11fe383255db8e5c3307319d470015616f27Bob Beers    if (ists & PMCC4_CPLD_INTR_CMT_4)
159350ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
159450ee11fe383255db8e5c3307319d470015616f27Bob Beers        handled |= 0x8;
159550ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (nciInterrupt[brdno][3] != NULL)
159650ee11fe383255db8e5c3307319d470015616f27Bob Beers            (*nciInterrupt[brdno][3]) ();
159750ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
159850ee11fe383255db8e5c3307319d470015616f27Bob Beers#if 0
159950ee11fe383255db8e5c3307319d470015616f27Bob Beers    /*** Test code just de-implements the asserted interrupt.  Alternate
160050ee11fe383255db8e5c3307319d470015616f27Bob Beers    vendor will supply COMET interrupt handling code herein or such.
160150ee11fe383255db8e5c3307319d470015616f27Bob Beers    ***/
160250ee11fe383255db8e5c3307319d470015616f27Bob Beers    pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
160350ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif
160450ee11fe383255db8e5c3307319d470015616f27Bob Beers
160550ee11fe383255db8e5c3307319d470015616f27Bob Beers    return IRQ_RETVAL (handled);
160650ee11fe383255db8e5c3307319d470015616f27Bob Beers}
160750ee11fe383255db8e5c3307319d470015616f27Bob Beers
160850ee11fe383255db8e5c3307319d470015616f27Bob Beers
160950ee11fe383255db8e5c3307319d470015616f27Bob Beersunsigned long
161050ee11fe383255db8e5c3307319d470015616f27Bob BeerswanpmcC4T1E1_getBaseAddress (int cardID, int deviceID)
161150ee11fe383255db8e5c3307319d470015616f27Bob Beers{
161250ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci_t       *ci;
161350ee11fe383255db8e5c3307319d470015616f27Bob Beers    unsigned long base = 0;
161450ee11fe383255db8e5c3307319d470015616f27Bob Beers
161550ee11fe383255db8e5c3307319d470015616f27Bob Beers    ci = c4_list;
161650ee11fe383255db8e5c3307319d470015616f27Bob Beers    while (ci)
161750ee11fe383255db8e5c3307319d470015616f27Bob Beers    {
161850ee11fe383255db8e5c3307319d470015616f27Bob Beers        if (ci->brdno == cardID)    /* found valid device */
161950ee11fe383255db8e5c3307319d470015616f27Bob Beers        {
162050ee11fe383255db8e5c3307319d470015616f27Bob Beers            if (deviceID < ci->max_port)        /* comet is supported */
162150ee11fe383255db8e5c3307319d470015616f27Bob Beers                base = ((unsigned long) ci->port[deviceID].cometbase);
162250ee11fe383255db8e5c3307319d470015616f27Bob Beers            break;
162350ee11fe383255db8e5c3307319d470015616f27Bob Beers        }
162450ee11fe383255db8e5c3307319d470015616f27Bob Beers        ci = ci->next;              /* next board, if any */
162550ee11fe383255db8e5c3307319d470015616f27Bob Beers    }
162650ee11fe383255db8e5c3307319d470015616f27Bob Beers    return (base);
162750ee11fe383255db8e5c3307319d470015616f27Bob Beers}
162850ee11fe383255db8e5c3307319d470015616f27Bob Beers
162950ee11fe383255db8e5c3307319d470015616f27Bob Beers#endif                          /*** CONFIG_SBE_PMCC4_NCOMM ***/
163050ee11fe383255db8e5c3307319d470015616f27Bob Beers
163150ee11fe383255db8e5c3307319d470015616f27Bob Beers
163250ee11fe383255db8e5c3307319d470015616f27Bob Beers/***  End-of-File  ***/
1633