/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Tektronix Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_hy.c 7.7 (Berkeley) 12/16/90
*/
/*
* 4.2 BSD Unix Kernel - Vax Network Interface Support
*
* $Header: if_hy.c,v 10.1 84/07/22 21:02:56 steveg Exp $
* $Locker: $
*
* Modifications from Berkeley 4.2 BSD
* Copyright (c) 1983, Tektronix Inc.
* All Rights Reserved
*
* $Log: if_hy.c,v $
* Revision 10.1 84/07/22 21:02:56 steveg
* define PI13 (moved from if_hyreg.h, somehow got dropped in the process)
* rework hywatch to check for power fails first
*
* Revision 10.0 84/06/30 19:54:27 steveg
* Big Build
*
* Revision 3.17 84/06/20 19:20:28 steveg
* increment hy_ntime in hywatch
* print out state name, csr, last command, and hy_flags when watchdog timer
* expires
*
* Revision 3.16 84/06/20 19:09:34 steveg
* turn on continuous logging by default
*
* Revision 3.15 84/05/30 22:19:09 steveg
* changes to reflect new layout ot statistics data
*
* Revision 3.14 84/05/30 19:25:15 steveg
* move driver states to if_hy.h so log printing programs can use them
*
* Revision 3.13 84/05/30 17:13:26 steveg
* make it compile
*
* Revision 3.12 84/05/30 13:46:16 steveg
* rework logging
*
* Revision 3.11 84/05/18 19:35:02 steveg
* clear IFF_RUNNING and IFF_UP on unibus reset to force resource allocation
* by the init routine
*
* Revision 3.10 84/05/04 12:14:44 steveg
* more rework to make it actually work under 4.2
*
* Revision 3.9 84/05/01 23:34:52 steveg
* fix typo so it compiles (unit -> ui->ui_unit)
*
* Revision 3.8 84/05/01 23:18:30 steveg
* changes after talking with rickk
* - check power off more closely
* - support remote loopback through A710 adapters
* - IMPLINK -> HYLINK
* - return EHOSTUNREACH on hyroute failure
* - bump if_collisions on abnormal interrupts that aren't input or output
*
*
*/
#include "hy.h"
#if NHY > 0
/*
* Network Systems Copropration Hyperchanel interface
*/
#include "../include/pte.h"
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/mbuf.h"
#include "sys/buf.h"
#include "sys/protosw.h"
#include "sys/socket.h"
#include "sys/vmmac.h"
#include "sys/errno.h"
#include "sys/time.h"
#include "sys/kernel.h"
#include "sys/ioctl.h"
#include "net/if.h"
#include "net/netisr.h"
#include "net/route.h"
#ifdef INET
#include "netinet/in.h"
#include "netinet/in_systm.h"
#include "netinet/in_var.h"
#include "netinet/ip.h"
#endif
#include "../include/cpu.h"
#include "../include/mtpr.h"
#include "../uba/ubareg.h"
#include "../uba/ubavar.h"
/*
* configuration specific paramters
* - change as appropriate for particular installaions
*/
#define HYROUTE
#define HYELOG
#define HYLOG
#define HYMTU 1100
#define PI13
#ifdef DEBUG
#define HYLOG
#endif
#include "if_hy.h"
#include "if_hyreg.h"
#include "if_uba.h"
int hyprobe(), hyattach(), hyinit(), hyioctl();
int hyoutput(), hyreset(), hywatch();
struct uba_device *hyinfo[NHY];
u_short hystd[] = { 0772410, 0 };
struct uba_driver hydriver =
{ hyprobe, 0, hyattach, 0, hystd, "hy", hyinfo };
/*
* Hyperchannel software status per interface.
*
* Each interface is referenced by a network interface structure,
* hy_if, which the routing code uses to locate the interface.
* This structure contains the output queue for the interface, its address, ...
* We also have, for each interface, a UBA interface structure, which
* contains information about the UNIBUS resources held by the interface:
* map registers, buffered data paths, etc. Information is cached in this
* structure for use by the if_uba.c routines in running the interface
* efficiently.
*/
struct hy_softc {
struct ifnet hy_if; /* network-visible interface */
struct ifuba hy_ifuba; /* UNIBUS resources */
short hy_flags; /* flags */
short hy_state; /* driver state */
u_short hy_host; /* local host number */
struct in_addr hy_addr; /* internet address */
int hy_olen; /* packet length on output */
int hy_lastwcr; /* last command's word count */
short hy_savedstate; /* saved for reissue after status */
short hy_savedcmd; /* saved command for reissue */
int hy_savedcount; /* saved byte count for reissue */
int hy_savedaddr; /* saved unibus address for reissue */
int hy_ntime; /* number of timeouts since last cmd */
int hy_retry; /* retry counter */
struct hy_stat hy_stat; /* statistics */
struct hy_status hy_status; /* status */
} hy_softc[NHY];
#ifdef HYELOG
u_long hy_elog[HYE_SIZE];
#endif
#ifdef HYLOG
struct hy_log hy_log;
#endif
#ifdef HYROUTE
struct hy_route hy_route[NHY];
#endif
#ifdef DEBUG
#define printL printf
#define printD if (hy_debug_flag) printf
int hy_debug_flag = 0;
/*
* hy_nodebug bit 0x01 set hy_debug_flag on hycancel
* hy_nodebug bit 0x02 set hy_debug_flag on command reissue
* hy_nodebug bit 0x04 set hy_debug_flag on abnormal interrupt
*/
int hy_nodebug = 0x0;
#endif
#define SCANINTERVAL 10 /* seconds */
#define MAXINTERVAL 20 /* seconds (max action) */
/*
* Cause a device interrupt. This code uses a buffer starting at
* location zero on the unibus (which is already mapped by the
* autoconfigure code in the kernel).
*/
hyprobe(reg)
caddr_t reg;
{
register int br, cvec; /* r11, r10 value-result */
register struct hydevice *addr = (struct hydevice *) reg;
#ifdef lint
br = 0; cvec = br; br = cvec;
hyint(0);
#endif
/*
* request adapter status to a buffer starting at unibus location 0
*/
addr->hyd_bar = 0;
addr->hyd_wcr = -((sizeof(struct hy_status) + 1) >> 1);
addr->hyd_dbuf = HYF_STATUS;
#ifdef PI13
addr->hyd_csr |= S_GO | S_IE | S_IATTN;
#else
addr->hyd_csr |= S_GO | S_IE;
#endif
DELAY(10000);
#ifdef PI13
addr->hyd_csr |= S_CLRINT; /* clear any stacked interrupts */
#endif
addr->hyd_csr &= ~(S_IE | S_CLRINT); /* disable further interrupts */
return(sizeof(struct hydevice));
}
/*
* Interface exists: make available by filling in network interface
* record. System will initialize the interface when it is ready
* to accept packets.
*/
hyattach(ui)
struct uba_device *ui;
{
register struct hy_softc *is = &hy_softc[ui->ui_unit];
register struct ifnet *ifp = &is->hy_if;
ifp->if_uni