1154899Srik/* 2154899Srik * Cronyx-Tau32-PCI adapter driver for FreeBSD. 3154899Srik * 4154899Srik * Copyright (C) 2003-2005 Cronyx Engineering. 5154899Srik * Copyright (C) 2003-2005 Kurakin Roman, <rik@FreeBSD.org> 6154899Srik * 7154899Srik * This software is distributed with NO WARRANTIES, not even the implied 8154899Srik * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 9154899Srik * 10154899Srik * Authors grant any other persons or organisations a permission to use, 11154899Srik * modify and redistribute this software in source and binary forms, 12154899Srik * as long as this message is kept with the software, all derivative 13154899Srik * works or modified versions. 14154899Srik * 15154899Srik * $Cronyx: if_ce.c,v 1.9.2.8 2005/11/21 14:17:44 rik Exp $ 16154899Srik */ 17154899Srik 18154899Srik#include <sys/cdefs.h> 19154899Srik__FBSDID("$FreeBSD: stable/11/sys/dev/ce/if_ce.c 315221 2017-03-14 02:06:03Z pfg $"); 20154899Srik 21154899Srik#include <sys/param.h> 22154899Srik 23154899Srik#if __FreeBSD_version >= 500000 24154899Srik# define NPCI 1 25154899Srik#else 26154899Srik# include "pci.h" 27154899Srik#endif 28154899Srik 29154899Srik#if NPCI > 0 30154899Srik 31154899Srik#include <sys/ucred.h> 32164033Srwatson#include <sys/priv.h> 33154899Srik#include <sys/proc.h> 34154899Srik#include <sys/systm.h> 35154899Srik#include <sys/mbuf.h> 36154899Srik#include <sys/kernel.h> 37154899Srik#include <sys/module.h> 38154899Srik#include <sys/conf.h> 39154899Srik#include <sys/malloc.h> 40154899Srik#include <sys/socket.h> 41154899Srik#include <sys/sockio.h> 42154899Srik#if __FreeBSD_version >= 504000 43154899Srik#include <sys/sysctl.h> 44154899Srik#endif 45154899Srik#include <sys/tty.h> 46154899Srik#include <sys/bus.h> 47154899Srik#include <vm/vm.h> 48154899Srik#include <vm/pmap.h> 49154899Srik#include <net/if.h> 50257176Sglebius#include <net/if_var.h> 51154899Srik#if __FreeBSD_version > 501000 52154899Srik# include <dev/pci/pcivar.h> 53154899Srik# include <dev/pci/pcireg.h> 54154899Srik#else 55154899Srik# include <pci/pcivar.h> 56154899Srik# include <pci/pcireg.h> 57154899Srik#endif 58154899Srik#include <machine/bus.h> 59154899Srik#include <sys/rman.h> 60154899Srik#include "opt_ng_cronyx.h" 61154899Srik#ifdef NETGRAPH_CRONYX 62154899Srik# include "opt_netgraph.h" 63154899Srik# ifndef NETGRAPH 64154899Srik# error #option NETGRAPH missed from configuration 65154899Srik# endif 66154899Srik# include <netgraph/ng_message.h> 67154899Srik# include <netgraph/netgraph.h> 68154899Srik# include <dev/ce/ng_ce.h> 69154899Srik#else 70154899Srik# include <net/if_types.h> 71154899Srik# include <net/if_sppp.h> 72154899Srik# define PP_CISCO IFF_LINK2 73154899Srik# include <net/bpf.h> 74154899Srik#endif 75154899Srik#include <dev/cx/machdep.h> 76154899Srik#include <dev/ce/ceddk.h> 77154899Srik#include <machine/cserial.h> 78154899Srik#include <machine/resource.h> 79154899Srik 80154899Srik/* If we don't have Cronyx's sppp version, we don't have fr support via sppp */ 81154899Srik#ifndef PP_FR 82154899Srik#define PP_FR 0 83154899Srik#endif 84154899Srik 85154899Srik#ifndef IFP2SP 86154899Srik#define IFP2SP(ifp) ((struct sppp*)ifp) 87154899Srik#endif 88154899Srik#ifndef SP2IFP 89154899Srik#define SP2IFP(sp) ((struct ifnet*)sp) 90154899Srik#endif 91154899Srik 92154899Srik#ifndef PCIR_BAR 93154899Srik#define PCIR_BAR(x) (PCIR_MAPS + (x) * 4) 94154899Srik#endif 95154899Srik 96154899Srik/* define as our previous return value */ 97154899Srik#ifndef BUS_PROBE_DEFAULT 98154899Srik#define BUS_PROBE_DEFAULT 0 99154899Srik#endif 100154899Srik 101154899Srik#define CE_DEBUG(d,s) ({if (d->chan->debug) {\ 102154899Srik printf ("%s: ", d->name); printf s;}}) 103154899Srik#define CE_DEBUG2(d,s) ({if (d->chan->debug>1) {\ 104154899Srik printf ("%s: ", d->name); printf s;}}) 105154899Srik 106154899Srik#ifndef IF_DRAIN 107154899Srik#define IF_DRAIN(ifq) do { \ 108154899Srik struct mbuf *m; \ 109154899Srik for (;;) { \ 110154899Srik IF_DEQUEUE(ifq, m); \ 111154899Srik if (m == NULL) \ 112154899Srik break; \ 113154899Srik m_freem(m); \ 114154899Srik } \ 115154899Srik} while (0) 116154899Srik#endif 117154899Srik 118154899Srik#ifndef _IF_QLEN 119154899Srik#define _IF_QLEN(ifq) ((ifq)->ifq_len) 120154899Srik#endif 121154899Srik 122154899Srik#ifndef callout_drain 123154899Srik#define callout_drain callout_stop 124154899Srik#endif 125154899Srik 126154899Srik#define CE_LOCK_NAME "ceX" 127154899Srik 128188663Srwatson#define CE_LOCK(_bd) mtx_lock (&(_bd)->ce_mtx) 129188663Srwatson#define CE_UNLOCK(_bd) mtx_unlock (&(_bd)->ce_mtx) 130188663Srwatson#define CE_LOCK_ASSERT(_bd) mtx_assert (&(_bd)->ce_mtx, MA_OWNED) 131154899Srik 132154899Srik#define CDEV_MAJOR 185 133154899Srik 134154899Srikstatic int ce_probe __P((device_t)); 135154899Srikstatic int ce_attach __P((device_t)); 136154899Srikstatic int ce_detach __P((device_t)); 137154899Srik 138154899Srikstatic device_method_t ce_methods[] = { 139154899Srik /* Device interface */ 140154899Srik DEVMETHOD(device_probe, ce_probe), 141154899Srik DEVMETHOD(device_attach, ce_attach), 142154899Srik DEVMETHOD(device_detach, ce_detach), 143154899Srik 144246128Ssbz DEVMETHOD_END 145154899Srik}; 146154899Srik 147154899Sriktypedef struct _ce_dma_mem_t { 148154899Srik unsigned long phys; 149154899Srik void *virt; 150154899Srik size_t size; 151154899Srik#if __FreeBSD_version >= 500000 152154899Srik bus_dma_tag_t dmat; 153154899Srik bus_dmamap_t mapp; 154154899Srik#endif 155154899Srik} ce_dma_mem_t; 156154899Srik 157154899Sriktypedef struct _drv_t { 158154899Srik char name [8]; 159154899Srik int running; 160154899Srik ce_board_t *board; 161154899Srik ce_chan_t *chan; 162154899Srik struct ifqueue rqueue; 163154899Srik#ifdef NETGRAPH 164193813Simp char nodename [NG_NODESIZE]; 165154899Srik hook_p hook; 166154899Srik hook_p debug_hook; 167154899Srik node_p node; 168154899Srik struct ifqueue queue; 169154899Srik struct ifqueue hi_queue; 170154899Srik#else 171154899Srik struct ifnet *ifp; 172154899Srik#endif 173199407Sjhb short timeout; 174199407Sjhb struct callout timeout_handle; 175154899Srik#if __FreeBSD_version >= 500000 176154899Srik struct cdev *devt; 177154899Srik#else /* __FreeBSD_version < 500000 */ 178154899Srik dev_t devt; 179154899Srik#endif 180154899Srik ce_dma_mem_t dmamem; 181154899Srik} drv_t; 182154899Srik 183154899Sriktypedef struct _bdrv_t { 184154899Srik ce_board_t *board; 185154899Srik struct resource *ce_res; 186154899Srik struct resource *ce_irq; 187154899Srik void *ce_intrhand; 188154899Srik ce_dma_mem_t dmamem; 189154899Srik drv_t channel [NCHAN]; 190154899Srik#if __FreeBSD_version >= 504000 191154899Srik struct mtx ce_mtx; 192154899Srik#endif 193154899Srik} bdrv_t; 194154899Srik 195154899Srikstatic driver_t ce_driver = { 196154899Srik "ce", 197154899Srik ce_methods, 198154899Srik sizeof(bdrv_t), 199154899Srik}; 200154899Srik 201154899Srikstatic devclass_t ce_devclass; 202154899Srik 203154899Srikstatic void ce_receive (ce_chan_t *c, unsigned char *data, int len); 204154899Srikstatic void ce_transmit (ce_chan_t *c, void *attachment, int len); 205154899Srikstatic void ce_error (ce_chan_t *c, int data); 206154899Srikstatic void ce_up (drv_t *d); 207154899Srikstatic void ce_start (drv_t *d); 208154899Srikstatic void ce_down (drv_t *d); 209154899Srikstatic void ce_watchdog (drv_t *d); 210199407Sjhbstatic void ce_watchdog_timer (void *arg); 211154899Srik#ifdef NETGRAPH 212154899Srikextern struct ng_type typestruct; 213154899Srik#else 214154899Srikstatic void ce_ifstart (struct ifnet *ifp); 215154899Srikstatic void ce_tlf (struct sppp *sp); 216154899Srikstatic void ce_tls (struct sppp *sp); 217154899Srikstatic int ce_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); 218154899Srikstatic void ce_initialize (void *softc); 219154899Srik#endif 220154899Srik 221154899Srikstatic ce_board_t *adapter [NBRD]; 222154899Srikstatic drv_t *channel [NBRD*NCHAN]; 223154899Srikstatic struct callout led_timo [NBRD]; 224154899Srikstatic struct callout timeout_handle; 225154899Srik 226154899Srikstatic int ce_destroy = 0; 227154899Srik 228155065Srik#if __FreeBSD_version < 500000 229155065Srikstatic int ce_open (dev_t dev, int oflags, int devtype, struct proc *p); 230155065Srikstatic int ce_close (dev_t dev, int fflag, int devtype, struct proc *p); 231155065Srikstatic int ce_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p); 232155065Srik#else 233155065Srikstatic int ce_open (struct cdev *dev, int oflags, int devtype, struct thread *td); 234155065Srikstatic int ce_close (struct cdev *dev, int fflag, int devtype, struct thread *td); 235155065Srikstatic int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td); 236155065Srik#endif 237155065Srik#if __FreeBSD_version < 500000 238155065Srikstatic struct cdevsw ce_cdevsw = { 239155065Srik ce_open, ce_close, noread, nowrite, 240155065Srik ce_ioctl, nopoll, nommap, nostrategy, 241155065Srik "ce", CDEV_MAJOR, nodump, nopsize, 242155065Srik D_NAGGED, -1 243155065Srik }; 244155065Srik#elif __FreeBSD_version == 500000 245155065Srikstatic struct cdevsw ce_cdevsw = { 246155065Srik ce_open, ce_close, noread, nowrite, 247155065Srik ce_ioctl, nopoll, nommap, nostrategy, 248155065Srik "ce", CDEV_MAJOR, nodump, nopsize, 249155065Srik D_NAGGED, 250155065Srik }; 251155065Srik#elif __FreeBSD_version <= 501000 252155065Srikstatic struct cdevsw ce_cdevsw = { 253155065Srik .d_open = ce_open, 254155065Srik .d_close = ce_close, 255155065Srik .d_read = noread, 256155065Srik .d_write = nowrite, 257155065Srik .d_ioctl = ce_ioctl, 258155065Srik .d_poll = nopoll, 259155065Srik .d_mmap = nommap, 260155065Srik .d_strategy = nostrategy, 261155065Srik .d_name = "ce", 262155065Srik .d_maj = CDEV_MAJOR, 263155065Srik .d_dump = nodump, 264155065Srik .d_flags = D_NAGGED, 265155065Srik}; 266155065Srik#elif __FreeBSD_version < 502103 267155065Srikstatic struct cdevsw ce_cdevsw = { 268155065Srik .d_open = ce_open, 269155065Srik .d_close = ce_close, 270155065Srik .d_ioctl = ce_ioctl, 271155065Srik .d_name = "ce", 272155065Srik .d_maj = CDEV_MAJOR, 273155065Srik .d_flags = D_NAGGED, 274155065Srik}; 275155065Srik#elif __FreeBSD_version < 600000 276155065Srikstatic struct cdevsw ce_cdevsw = { 277155065Srik .d_version = D_VERSION, 278155065Srik .d_open = ce_open, 279155065Srik .d_close = ce_close, 280155065Srik .d_ioctl = ce_ioctl, 281155065Srik .d_name = "ce", 282155065Srik .d_maj = CDEV_MAJOR, 283155065Srik .d_flags = D_NEEDGIANT, 284155065Srik}; 285155065Srik#else /* __FreeBSD_version >= 600000 */ 286155065Srikstatic struct cdevsw ce_cdevsw = { 287155065Srik .d_version = D_VERSION, 288155065Srik .d_open = ce_open, 289155065Srik .d_close = ce_close, 290155065Srik .d_ioctl = ce_ioctl, 291155065Srik .d_name = "ce", 292155065Srik}; 293155065Srik#endif 294155065Srik 295154899Srik/* 296154899Srik * Make an mbuf from data. 297154899Srik */ 298154899Srikstatic struct mbuf *makembuf (void *buf, unsigned len) 299154899Srik{ 300154899Srik struct mbuf *m; 301154899Srik 302243857Sglebius MGETHDR (m, M_NOWAIT, MT_DATA); 303154899Srik if (! m) 304154899Srik return 0; 305276750Srwatson if (!(MCLGET(m, M_NOWAIT))) { 306154899Srik m_freem (m); 307154899Srik return 0; 308154899Srik } 309154899Srik m->m_pkthdr.len = m->m_len = len; 310154899Srik bcopy (buf, mtod (m, caddr_t), len); 311154899Srik return m; 312154899Srik} 313154899Srik 314154899Srikstatic int ce_probe (device_t dev) 315154899Srik{ 316154899Srik if ((pci_get_vendor (dev) == TAU32_PCI_VENDOR_ID) && 317154899Srik (pci_get_device (dev) == TAU32_PCI_DEVICE_ID)) { 318154899Srik device_set_desc (dev, "Cronyx-Tau32-PCI serial adapter"); 319154899Srik return BUS_PROBE_DEFAULT; 320154899Srik } 321154899Srik return ENXIO; 322154899Srik} 323154899Srik 324154899Srikstatic void ce_timeout (void *arg) 325154899Srik{ 326154899Srik drv_t *d; 327154899Srik int s, i, k; 328154899Srik 329154899Srik for (i = 0; i < NBRD; ++i) { 330154899Srik if (adapter[i] == NULL) 331154899Srik continue; 332154899Srik for (k = 0; k < NCHAN; ++k) { 333154899Srik s = splimp (); 334154899Srik if (ce_destroy) { 335154899Srik splx (s); 336154899Srik return; 337154899Srik } 338154899Srik d = channel[i * NCHAN + k]; 339154899Srik if (!d) { 340154899Srik splx (s); 341154899Srik continue; 342154899Srik } 343154899Srik CE_LOCK ((bdrv_t *)d->board->sys); 344154899Srik switch (d->chan->type) { 345154899Srik case T_E1: 346154899Srik ce_e1_timer (d->chan); 347154899Srik break; 348154899Srik default: 349154899Srik break; 350154899Srik } 351154899Srik CE_UNLOCK ((bdrv_t *)d->board->sys); 352154899Srik splx (s); 353154899Srik } 354154899Srik } 355154899Srik s = splimp (); 356154899Srik if (!ce_destroy) 357154899Srik callout_reset (&timeout_handle, hz, ce_timeout, 0); 358154899Srik splx (s); 359154899Srik} 360154899Srik 361154899Srikstatic void ce_led_off (void *arg) 362154899Srik{ 363154899Srik ce_board_t *b = arg; 364154899Srik bdrv_t *bd = (bdrv_t *) b->sys; 365154899Srik int s; 366154899Srik s = splimp (); 367154899Srik if (ce_destroy) { 368154899Srik splx (s); 369154899Srik return; 370154899Srik } 371154899Srik CE_LOCK (bd); 372154899Srik TAU32_LedSet (b->ddk.pControllerObject, 0); 373154899Srik CE_UNLOCK (bd); 374154899Srik splx (s); 375154899Srik} 376154899Srik 377154899Srikstatic void ce_intr (void *arg) 378154899Srik{ 379154899Srik bdrv_t *bd = arg; 380154899Srik ce_board_t *b = bd->board; 381154899Srik int s; 382154899Srik int i; 383154899Srik#if __FreeBSD_version >= 500000 && defined NETGRAPH 384154899Srik int error; 385154899Srik#endif 386154899Srik s = splimp (); 387154899Srik if (ce_destroy) { 388154899Srik splx (s); 389154899Srik return; 390154899Srik } 391154899Srik CE_LOCK (bd); 392154899Srik /* Turn LED on. */ 393154899Srik TAU32_LedSet (b->ddk.pControllerObject, 1); 394154899Srik 395154899Srik TAU32_HandleInterrupt (b->ddk.pControllerObject); 396154899Srik 397154899Srik /* Turn LED off 50 msec later. */ 398154899Srik callout_reset (&led_timo[b->num], hz/20, ce_led_off, b); 399154899Srik CE_UNLOCK (bd); 400154899Srik splx (s); 401154899Srik 402154899Srik /* Pass packets in a lock-free state */ 403154899Srik for (i = 0; i < NCHAN && b->chan[i].type; i++) { 404154899Srik drv_t *d = b->chan[i].sys; 405154899Srik struct mbuf *m; 406154899Srik if (!d || !d->running) 407154899Srik continue; 408154899Srik while (_IF_QLEN(&d->rqueue)) { 409154899Srik IF_DEQUEUE (&d->rqueue,m); 410154899Srik if (!m) 411154899Srik continue; 412154899Srik#ifdef NETGRAPH 413154899Srik if (d->hook) { 414154899Srik#if __FreeBSD_version >= 500000 415154899Srik NG_SEND_DATA_ONLY (error, d->hook, m); 416154899Srik#else 417154899Srik ng_queue_data (d->hook, m, 0); 418154899Srik#endif 419154899Srik } else { 420154899Srik IF_DRAIN (&d->rqueue); 421154899Srik } 422154899Srik#else 423154899Srik sppp_input (d->ifp, m); 424154899Srik#endif 425154899Srik } 426154899Srik } 427154899Srik} 428154899Srik 429154899Srik#if __FreeBSD_version >= 500000 430154899Srikstatic void 431154899Srikce_bus_dmamap_addr (void *arg, bus_dma_segment_t *segs, int nseg, int error) 432154899Srik{ 433154899Srik unsigned long *addr; 434154899Srik 435154899Srik if (error) 436154899Srik return; 437154899Srik 438154899Srik KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg)); 439154899Srik addr = arg; 440154899Srik *addr = segs->ds_addr; 441154899Srik} 442154899Srik 443154899Srik#ifndef BUS_DMA_ZERO 444154899Srik#define BUS_DMA_ZERO 0 445154899Srik#endif 446154899Srik 447154899Srikstatic int 448154899Srikce_bus_dma_mem_alloc (int bnum, int cnum, ce_dma_mem_t *dmem) 449154899Srik{ 450154899Srik int error; 451154899Srik 452154899Srik error = bus_dma_tag_create (NULL, 16, 0, BUS_SPACE_MAXADDR_32BIT, 453154899Srik BUS_SPACE_MAXADDR, NULL, NULL, dmem->size, 1, 454154899Srik dmem->size, 0, 455154899Srik#if __FreeBSD_version >= 502000 456154899Srik NULL, NULL, 457154899Srik#endif 458154899Srik &dmem->dmat); 459154899Srik if (error) { 460154899Srik if (cnum >= 0) printf ("ce%d-%d: ", bnum, cnum); 461154899Srik else printf ("ce%d: ", bnum); 462154899Srik printf ("couldn't allocate tag for dma memory\n"); 463154899Srik return 0; 464154899Srik } 465154899Srik error = bus_dmamem_alloc (dmem->dmat, (void **)&dmem->virt, 466154899Srik BUS_DMA_NOWAIT | BUS_DMA_ZERO, &dmem->mapp); 467154899Srik if (error) { 468154899Srik if (cnum >= 0) printf ("ce%d-%d: ", bnum, cnum); 469154899Srik else printf ("ce%d: ", bnum); 470154899Srik printf ("couldn't allocate mem for dma memory\n"); 471154899Srik bus_dma_tag_destroy (dmem->dmat); 472154899Srik return 0; 473154899Srik } 474154899Srik error = bus_dmamap_load (dmem->dmat, dmem->mapp, dmem->virt, 475154899Srik dmem->size, ce_bus_dmamap_addr, &dmem->phys, 0); 476154899Srik if (error) { 477154899Srik if (cnum >= 0) printf ("ce%d-%d: ", bnum, cnum); 478154899Srik else printf ("ce%d: ", bnum); 479154899Srik printf ("couldn't load mem map for dma memory\n"); 480154899Srik bus_dmamem_free (dmem->dmat, dmem->virt, dmem->mapp); 481154899Srik bus_dma_tag_destroy (dmem->dmat); 482154899Srik return 0; 483154899Srik } 484154899Srik#if __FreeBSD_version >= 502000 485154899Srik bzero (dmem->virt, dmem->size); 486154899Srik#endif 487154899Srik return 1; 488154899Srik} 489154899Srik 490154899Srikstatic void 491154899Srikce_bus_dma_mem_free (ce_dma_mem_t *dmem) 492154899Srik{ 493154899Srik bus_dmamap_unload (dmem->dmat, dmem->mapp); 494154899Srik bus_dmamem_free (dmem->dmat, dmem->virt, dmem->mapp); 495154899Srik bus_dma_tag_destroy (dmem->dmat); 496154899Srik} 497154899Srik#else 498154899Srikstatic int 499154899Srikce_bus_dma_mem_alloc (int bnum, int cnum, ce_dma_mem_t *dmem) 500154899Srik{ 501154899Srik dmem->virt = contigmalloc (dmem->size, M_DEVBUF, M_WAITOK, 502154899Srik 0x100000, 0xffffffff, 16, 0); 503154899Srik if (dmem->virt == NULL) { 504154899Srik if (cnum >= 0) printf ("ce%d-%d: ", bnum, cnum); 505154899Srik else printf ("ce%d: ", bnum); 506154899Srik printf ("couldn't allocate dma memory\n"); 507154899Srik return 0; 508154899Srik } 509154899Srik dmem->phys = vtophys (dmem->virt); 510154899Srik bzero (dmem->virt, dmem->size); 511154899Srik return 1; 512154899Srik} 513154899Srik 514154899Srikstatic void 515154899Srikce_bus_dma_mem_free (ce_dma_mem_t *dmem) 516154899Srik{ 517154899Srik contigfree (dmem->virt, dmem->size, M_DEVBUF); 518154899Srik} 519154899Srik#endif 520154899Srik 521154899Srik/* 522154899Srik * Called if the probe succeeded. 523154899Srik */ 524154899Srikstatic int ce_attach (device_t dev) 525154899Srik{ 526154899Srik bdrv_t *bd = device_get_softc (dev); 527154899Srik int unit = device_get_unit (dev); 528154899Srik#if __FreeBSD_version >= 504000 529154899Srik char *ce_ln = CE_LOCK_NAME; 530154899Srik#endif 531154899Srik vm_offset_t vbase; 532154899Srik int rid, error; 533154899Srik ce_board_t *b; 534154899Srik ce_chan_t *c; 535154899Srik drv_t *d; 536154899Srik int s; 537154899Srik 538154899Srik b = malloc (sizeof(ce_board_t), M_DEVBUF, M_WAITOK); 539154899Srik if (!b) { 540154899Srik printf ("ce%d: couldn't allocate memory\n", unit); 541154899Srik return (ENXIO); 542154899Srik } 543154899Srik bzero (b, sizeof(ce_board_t)); 544154899Srik 545154899Srik b->ddk.sys = &b; 546154899Srik 547154899Srik#if __FreeBSD_version >= 440000 548154899Srik pci_enable_busmaster (dev); 549154899Srik#endif 550154899Srik 551154899Srik bd->dmamem.size = TAU32_ControllerObjectSize; 552154899Srik if (! ce_bus_dma_mem_alloc (unit, -1, &bd->dmamem)) { 553154899Srik free (b, M_DEVBUF); 554154899Srik return (ENXIO); 555154899Srik } 556154899Srik b->ddk.pControllerObject = bd->dmamem.virt; 557154899Srik 558154899Srik bd->board = b; 559154899Srik b->sys = bd; 560154899Srik rid = PCIR_BAR(0); 561154899Srik bd->ce_res = bus_alloc_resource (dev, SYS_RES_MEMORY, &rid, 562154899Srik 0, ~0, 1, RF_ACTIVE); 563154899Srik if (! bd->ce_res) { 564154899Srik printf ("ce%d: cannot map memory\n", unit); 565154899Srik ce_bus_dma_mem_free (&bd->dmamem); 566154899Srik free (b, M_DEVBUF); 567154899Srik return (ENXIO); 568154899Srik } 569154899Srik vbase = (vm_offset_t) rman_get_virtual (bd->ce_res); 570154899Srik 571154899Srik b->ddk.PciBar1VirtualAddress = (void *)vbase; 572154899Srik b->ddk.ControllerObjectPhysicalAddress = bd->dmamem.phys; 573154899Srik b->ddk.pErrorNotifyCallback = ce_error_callback; 574154899Srik b->ddk.pStatusNotifyCallback = ce_status_callback; 575154899Srik b->num = unit; 576154899Srik 577154899Srik TAU32_BeforeReset(&b->ddk); 578154899Srik pci_write_config (dev, TAU32_PCI_RESET_ADDRESS, TAU32_PCI_RESET_ON, 4); 579154899Srik pci_write_config (dev, TAU32_PCI_RESET_ADDRESS, TAU32_PCI_RESET_OFF, 4); 580154899Srik 581154899Srik if(!TAU32_Initialize(&b->ddk, 0)) 582154899Srik { 583154899Srik printf ("ce%d: init adapter error 0x%08x, bus dead bits 0x%08lx\n", 584154899Srik unit, b->ddk.InitErrors, b->ddk.DeadBits); 585154899Srik bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->ce_res); 586154899Srik ce_bus_dma_mem_free (&bd->dmamem); 587154899Srik free (b, M_DEVBUF); 588154899Srik return (ENXIO); 589154899Srik } 590154899Srik 591154899Srik s = splimp (); 592154899Srik 593154899Srik ce_init_board (b); 594154899Srik 595154899Srik rid = 0; 596154899Srik bd->ce_irq = bus_alloc_resource (dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 597154899Srik RF_SHAREABLE | RF_ACTIVE); 598154899Srik if (! bd->ce_irq) { 599154899Srik printf ("ce%d: cannot map interrupt\n", unit); 600154899Srik bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->ce_res); 601154899Srik ce_bus_dma_mem_free (&bd->dmamem); 602154899Srik free (b, M_DEVBUF); 603154899Srik splx (s); 604154899Srik return (ENXIO); 605154899Srik } 606154899Srik#if __FreeBSD_version >= 500000 607283291Sjkim callout_init (&led_timo[unit], 1); 608154899Srik#else 609154899Srik callout_init (&led_timo[unit]); 610154899Srik#endif 611154899Srik error = bus_setup_intr (dev, bd->ce_irq, 612154899Srik#if __FreeBSD_version >= 500013 613188663Srwatson INTR_TYPE_NET|INTR_MPSAFE, 614154899Srik#else 615154899Srik INTR_TYPE_NET, 616154899Srik#endif 617166901Spiso NULL, ce_intr, bd, &bd->ce_intrhand); 618154899Srik if (error) { 619154899Srik printf ("ce%d: cannot set up irq\n", unit); 620154899Srik bus_release_resource (dev, SYS_RES_IRQ, 0, bd->ce_irq); 621154899Srik bus_release_resource (dev, SYS_RES_MEMORY, 622154899Srik PCIR_BAR(0), bd->ce_res); 623154899Srik ce_bus_dma_mem_free (&bd->dmamem); 624154899Srik free (b, M_DEVBUF); 625154899Srik splx (s); 626154899Srik return (ENXIO); 627154899Srik } 628154899Srik 629154899Srik switch (b->ddk.Model) { 630154899Srik case 1: strcpy (b->name, TAU32_BASE_NAME); break; 631154899Srik case 2: strcpy (b->name, TAU32_LITE_NAME); break; 632154899Srik case 3: strcpy (b->name, TAU32_ADPCM_NAME); break; 633154899Srik default: strcpy (b->name, TAU32_UNKNOWN_NAME); break; 634154899Srik } 635154899Srik 636154899Srik printf ("ce%d: %s\n", unit, b->name); 637154899Srik 638154899Srik for (c = b->chan; c < b->chan + NCHAN; ++c) { 639154899Srik c->num = (c - b->chan); 640154899Srik c->board = b; 641154899Srik 642154899Srik d = &bd->channel[c->num]; 643154899Srik d->dmamem.size = sizeof(ce_buf_t); 644154899Srik if (! ce_bus_dma_mem_alloc (unit, c->num, &d->dmamem)) 645154899Srik continue; 646154899Srik 647154899Srik channel [b->num * NCHAN + c->num] = d; 648154899Srik sprintf (d->name, "ce%d.%d", b->num, c->num); 649154899Srik d->board = b; 650154899Srik d->chan = c; 651154899Srik c->sys = d; 652154899Srik } 653154899Srik 654154899Srik for (c = b->chan; c < b->chan + NCHAN; ++c) { 655154899Srik if (c->sys == NULL) 656154899Srik continue; 657154899Srik d = c->sys; 658154899Srik 659283291Sjkim callout_init (&d->timeout_handle, 1); 660154899Srik#ifdef NETGRAPH 661154899Srik if (ng_make_node_common (&typestruct, &d->node) != 0) { 662154899Srik printf ("%s: cannot make common node\n", d->name); 663154899Srik d->node = NULL; 664154899Srik continue; 665154899Srik } 666154899Srik#if __FreeBSD_version >= 500000 667154899Srik NG_NODE_SET_PRIVATE (d->node, d); 668154899Srik#else 669154899Srik d->node->private = d; 670154899Srik#endif 671154899Srik sprintf (d->nodename, "%s%d", NG_CE_NODE_TYPE, 672154899Srik c->board->num * NCHAN + c->num); 673154899Srik if (ng_name_node (d->node, d->nodename)) { 674154899Srik printf ("%s: cannot name node\n", d->nodename); 675154899Srik#if __FreeBSD_version >= 500000 676154899Srik NG_NODE_UNREF (d->node); 677154899Srik#else 678154899Srik ng_rmnode (d->node); 679154899Srik ng_unref (d->node); 680154899Srik#endif 681154899Srik continue; 682154899Srik } 683207554Ssobomax d->queue.ifq_maxlen = ifqmaxlen; 684207554Ssobomax d->hi_queue.ifq_maxlen = ifqmaxlen; 685207554Ssobomax d->rqueue.ifq_maxlen = ifqmaxlen; 686154899Srik#if __FreeBSD_version >= 500000 687154899Srik mtx_init (&d->queue.ifq_mtx, "ce_queue", NULL, MTX_DEF); 688154899Srik mtx_init (&d->hi_queue.ifq_mtx, "ce_queue_hi", NULL, MTX_DEF); 689154899Srik mtx_init (&d->rqueue.ifq_mtx, "ce_rqueue", NULL, MTX_DEF); 690154899Srik#endif 691154899Srik#else /*NETGRAPH*/ 692154899Srik#if __FreeBSD_version >= 600031 693154899Srik d->ifp = if_alloc(IFT_PPP); 694154899Srik#else 695154899Srik d->ifp = malloc (sizeof(struct sppp), M_DEVBUF, M_WAITOK); 696154899Srik bzero (d->ifp, sizeof(struct sppp)); 697154899Srik#endif 698154899Srik if (!d->ifp) { 699154899Srik printf ("%s: cannot if_alloc() interface\n", d->name); 700154899Srik continue; 701154899Srik } 702154899Srik d->ifp->if_softc = d; 703154899Srik#if __FreeBSD_version > 501000 704154899Srik if_initname (d->ifp, "ce", b->num * NCHAN + c->num); 705154899Srik#else 706154899Srik d->ifp->if_unit = b->num * NCHAN + c->num; 707154899Srik d->ifp->if_name = "ce"; 708154899Srik#endif 709154899Srik d->ifp->if_mtu = PP_MTU; 710154899Srik d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 711154899Srik d->ifp->if_ioctl = ce_sioctl; 712154899Srik d->ifp->if_start = ce_ifstart; 713154899Srik d->ifp->if_init = ce_initialize; 714207554Ssobomax d->rqueue.ifq_maxlen = ifqmaxlen; 715154899Srik#if __FreeBSD_version >= 500000 716154899Srik mtx_init (&d->rqueue.ifq_mtx, "ce_rqueue", NULL, MTX_DEF); 717154899Srik#endif 718154899Srik sppp_attach (d->ifp); 719154899Srik if_attach (d->ifp); 720154899Srik IFP2SP(d->ifp)->pp_tlf = ce_tlf; 721154899Srik IFP2SP(d->ifp)->pp_tls = ce_tls; 722154899Srik /* If BPF is in the kernel, call the attach for it. 723154899Srik * The header size of PPP or Cisco/HDLC is 4 bytes. */ 724154899Srik bpfattach (d->ifp, DLT_PPP, 4); 725154899Srik#endif /*NETGRAPH*/ 726154899Srik ce_start_chan (c, 1, 1, d->dmamem.virt, d->dmamem.phys); 727154899Srik 728154899Srik /* Register callback functions. */ 729154899Srik ce_register_transmit (c, &ce_transmit); 730154899Srik ce_register_receive (c, &ce_receive); 731154899Srik ce_register_error (c, &ce_error); 732154899Srik d->devt = make_dev (&ce_cdevsw, b->num*NCHAN+c->num, UID_ROOT, 733154899Srik GID_WHEEL, 0600, "ce%d", b->num*NCHAN+c->num); 734154899Srik } 735154899Srik 736154899Srik#if __FreeBSD_version >= 504000 737154899Srik ce_ln[2] = '0' + unit; 738154899Srik mtx_init (&bd->ce_mtx, ce_ln, MTX_NETWORK_LOCK, MTX_DEF|MTX_RECURSE); 739154899Srik#endif 740154899Srik CE_LOCK (bd); 741154899Srik TAU32_EnableInterrupts(b->ddk.pControllerObject); 742154899Srik adapter[unit] = b; 743154899Srik CE_UNLOCK (bd); 744154899Srik splx (s); 745154899Srik 746154899Srik return 0; 747154899Srik} 748154899Srik 749154899Srikstatic int ce_detach (device_t dev) 750154899Srik{ 751154899Srik bdrv_t *bd = device_get_softc (dev); 752154899Srik ce_board_t *b = bd->board; 753154899Srik ce_chan_t *c; 754154899Srik int s; 755154899Srik 756154899Srik#if __FreeBSD_version >= 504000 757154899Srik KASSERT (mtx_initialized (&bd->ce_mtx), ("ce mutex not initialized")); 758154899Srik#endif 759154899Srik s = splimp (); 760154899Srik CE_LOCK (bd); 761154899Srik /* Check if the device is busy (open). */ 762154899Srik for (c = b->chan; c < b->chan + NCHAN; ++c) { 763154899Srik drv_t *d = (drv_t*) c->sys; 764154899Srik 765154899Srik /* XXX Non existen chan! */ 766154899Srik if (! d || ! d->chan) 767154899Srik continue; 768154899Srik if (d->running) { 769154899Srik CE_UNLOCK (bd); 770154899Srik splx (s); 771154899Srik return EBUSY; 772154899Srik } 773154899Srik } 774154899Srik 775154899Srik /* Ok, we can unload driver */ 776154899Srik /* At first we should disable interrupts */ 777154899Srik ce_destroy = 1; 778154899Srik TAU32_DisableInterrupts(b->ddk.pControllerObject); 779154899Srik 780154899Srik callout_stop (&led_timo[b->num]); 781154899Srik 782154899Srik for (c = b->chan; c < b->chan + NCHAN; ++c) { 783154899Srik drv_t *d = (drv_t*) c->sys; 784154899Srik 785154899Srik if (! d || ! d->chan) 786154899Srik continue; 787199407Sjhb callout_stop (&d->timeout_handle); 788154899Srik#ifndef NETGRAPH 789154899Srik /* Detach from the packet filter list of interfaces. */ 790154899Srik bpfdetach (d->ifp); 791167882Srik 792154899Srik /* Detach from the sync PPP list. */ 793154899Srik sppp_detach (d->ifp); 794154899Srik 795154899Srik /* Detach from the system list of interfaces. */ 796154899Srik if_detach (d->ifp); 797154899Srik#if __FreeBSD_version > 600031 798154899Srik if_free(d->ifp); 799154899Srik#else 800154899Srik free (d->ifp, M_DEVBUF); 801154899Srik#endif 802154899Srik 803154899Srik IF_DRAIN (&d->rqueue); 804154899Srik#if __FreeBSD_version >= 500000 805154899Srik mtx_destroy (&d->rqueue.ifq_mtx); 806154899Srik#endif 807154899Srik#else 808154899Srik#if __FreeBSD_version >= 500000 809154899Srik if (d->node) { 810154899Srik ng_rmnode_self (d->node); 811154899Srik NG_NODE_UNREF (d->node); 812154899Srik d->node = NULL; 813154899Srik } 814154899Srik IF_DRAIN (&d->rqueue); 815154899Srik mtx_destroy (&d->queue.ifq_mtx); 816154899Srik mtx_destroy (&d->hi_queue.ifq_mtx); 817154899Srik mtx_destroy (&d->rqueue.ifq_mtx); 818154899Srik#else 819154899Srik ng_rmnode (d->node); 820154899Srik d->node = 0; 821154899Srik#endif 822154899Srik#endif 823154899Srik destroy_dev (d->devt); 824154899Srik } 825154899Srik 826154899Srik CE_UNLOCK (bd); 827154899Srik splx (s); 828154899Srik 829154899Srik callout_drain (&led_timo[b->num]); 830154899Srik 831154899Srik /* Disable the interrupt request. */ 832154899Srik bus_teardown_intr (dev, bd->ce_irq, bd->ce_intrhand); 833154899Srik bus_release_resource (dev, SYS_RES_IRQ, 0, bd->ce_irq); 834154899Srik TAU32_DestructiveHalt (b->ddk.pControllerObject, 0); 835154899Srik bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->ce_res); 836154899Srik 837154899Srik for (c = b->chan; c < b->chan + NCHAN; ++c) { 838154899Srik drv_t *d = (drv_t*) c->sys; 839154899Srik 840154899Srik if (! d || ! d->chan) 841154899Srik continue; 842199407Sjhb callout_drain (&d->timeout_handle); 843315221Spfg channel [b->num * NCHAN + c->num] = NULL; 844154899Srik /* Deallocate buffers. */ 845154899Srik ce_bus_dma_mem_free (&d->dmamem); 846154899Srik } 847315221Spfg adapter [b->num] = NULL; 848154899Srik ce_bus_dma_mem_free (&bd->dmamem); 849154899Srik free (b, M_DEVBUF); 850154899Srik#if __FreeBSD_version >= 504000 851154899Srik mtx_destroy (&bd->ce_mtx); 852154899Srik#endif 853154899Srik return 0; 854154899Srik} 855154899Srik 856154899Srik#ifndef NETGRAPH 857154899Srikstatic void ce_ifstart (struct ifnet *ifp) 858154899Srik{ 859154899Srik drv_t *d = ifp->if_softc; 860154899Srik bdrv_t *bd = d->board->sys; 861154899Srik 862154899Srik CE_LOCK (bd); 863154899Srik ce_start (d); 864154899Srik CE_UNLOCK (bd); 865154899Srik} 866154899Srik 867154899Srikstatic void ce_tlf (struct sppp *sp) 868154899Srik{ 869154899Srik drv_t *d = SP2IFP(sp)->if_softc; 870154899Srik 871154899Srik CE_DEBUG2 (d, ("ce_tlf\n")); 872154899Srik sp->pp_down (sp); 873154899Srik} 874154899Srik 875154899Srikstatic void ce_tls (struct sppp *sp) 876154899Srik{ 877154899Srik drv_t *d = SP2IFP(sp)->if_softc; 878154899Srik 879154899Srik CE_DEBUG2 (d, ("ce_tls\n")); 880154899Srik sp->pp_up (sp); 881154899Srik} 882154899Srik 883154899Srik/* 884154899Srik * Process an ioctl request. 885154899Srik */ 886154899Srikstatic int ce_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data) 887154899Srik{ 888154899Srik drv_t *d = ifp->if_softc; 889154899Srik bdrv_t *bd = d->board->sys; 890154899Srik int error, s, was_up, should_be_up; 891154899Srik 892154899Srik#if __FreeBSD_version >= 600034 893154899Srik was_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; 894154899Srik#else 895154899Srik was_up = (ifp->if_flags & IFF_RUNNING) != 0; 896154899Srik#endif 897154899Srik error = sppp_ioctl (ifp, cmd, data); 898154899Srik 899154899Srik if (error) 900154899Srik return error; 901154899Srik 902154899Srik if (! (ifp->if_flags & IFF_DEBUG)) 903154899Srik d->chan->debug = 0; 904180132Srik else 905180132Srik d->chan->debug = d->chan->debug_shadow; 906154899Srik 907154899Srik switch (cmd) { 908154899Srik default: CE_DEBUG2 (d, ("ioctl 0x%lx\n", cmd)); return 0; 909154899Srik case SIOCADDMULTI: CE_DEBUG2 (d, ("ioctl SIOCADDMULTI\n")); return 0; 910154899Srik case SIOCDELMULTI: CE_DEBUG2 (d, ("ioctl SIOCDELMULTI\n")); return 0; 911154899Srik case SIOCSIFFLAGS: CE_DEBUG2 (d, ("ioctl SIOCSIFFLAGS\n")); break; 912154899Srik case SIOCSIFADDR: CE_DEBUG2 (d, ("ioctl SIOCSIFADDR\n")); break; 913154899Srik } 914154899Srik 915154899Srik /* We get here only in case of SIFFLAGS or SIFADDR. */ 916154899Srik s = splimp (); 917154899Srik CE_LOCK (bd); 918154899Srik#if __FreeBSD_version >= 600034 919154899Srik should_be_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; 920154899Srik#else 921154899Srik should_be_up = (ifp->if_flags & IFF_RUNNING) != 0; 922154899Srik#endif 923154899Srik if (! was_up && should_be_up) { 924154899Srik /* Interface goes up -- start it. */ 925154899Srik ce_up (d); 926154899Srik ce_start (d); 927154899Srik } else if (was_up && ! should_be_up) { 928154899Srik /* Interface is going down -- stop it. */ 929154899Srik/* if ((IFP2SP(ifp)->pp_flags & PP_FR) || (ifp->if_flags & PP_CISCO))*/ 930154899Srik ce_down (d); 931154899Srik } 932154899Srik CE_DEBUG (d, ("ioctl 0x%lx p4\n", cmd)); 933154899Srik CE_UNLOCK (bd); 934154899Srik splx (s); 935154899Srik return 0; 936154899Srik} 937154899Srik 938154899Srik/* 939154899Srik * Initialization of interface. 940154899Srik * It seems to be never called by upper level? 941154899Srik */ 942154899Srikstatic void ce_initialize (void *softc) 943154899Srik{ 944154899Srik drv_t *d = softc; 945154899Srik 946154899Srik CE_DEBUG (d, ("ce_initialize\n")); 947154899Srik} 948154899Srik#endif /*NETGRAPH*/ 949154899Srik 950154899Srik/* 951154899Srik * Stop the interface. Called on splimp(). 952154899Srik */ 953154899Srikstatic void ce_down (drv_t *d) 954154899Srik{ 955154899Srik CE_DEBUG (d, ("ce_down\n")); 956154899Srik /* Interface is going down -- stop it. */ 957154899Srik ce_set_dtr (d->chan, 0); 958154899Srik ce_set_rts (d->chan, 0); 959154899Srik 960154899Srik d->running = 0; 961199407Sjhb callout_stop (&d->timeout_handle); 962154899Srik} 963154899Srik 964154899Srik/* 965154899Srik * Start the interface. Called on splimp(). 966154899Srik */ 967154899Srikstatic void ce_up (drv_t *d) 968154899Srik{ 969154899Srik CE_DEBUG (d, ("ce_up\n")); 970154899Srik ce_set_dtr (d->chan, 1); 971154899Srik ce_set_rts (d->chan, 1); 972154899Srik 973154899Srik d->running = 1; 974154899Srik} 975154899Srik 976154899Srik/* 977154899Srik * Start output on the interface. Get another datagram to send 978154899Srik * off of the interface queue, and copy it to the interface 979154899Srik * before starting the output. 980154899Srik */ 981154899Srikstatic void ce_send (drv_t *d) 982154899Srik{ 983154899Srik struct mbuf *m; 984154899Srik u_short len; 985154899Srik 986154899Srik CE_DEBUG2 (d, ("ce_send\n")); 987154899Srik 988154899Srik /* No output if the interface is down. */ 989154899Srik if (! d->running) 990154899Srik return; 991154899Srik 992154899Srik while (ce_transmit_space (d->chan)) { 993154899Srik /* Get the packet to send. */ 994154899Srik#ifdef NETGRAPH 995154899Srik IF_DEQUEUE (&d->hi_queue, m); 996154899Srik if (! m) 997154899Srik IF_DEQUEUE (&d->queue, m); 998154899Srik#else 999154899Srik m = sppp_dequeue (d->ifp); 1000154899Srik#endif 1001154899Srik if (! m) 1002154899Srik return; 1003154899Srik#ifndef NETGRAPH 1004154899Srik#if __FreeBSD_version >= 500000 1005165632Sjhb BPF_MTAP (d->ifp, m); 1006154899Srik#else 1007165632Sjhb if (d->ifp->if_bpf) 1008154899Srik bpf_mtap (d->ifp, m); 1009154899Srik#endif 1010154899Srik#endif 1011154899Srik#if __FreeBSD_version >= 490000 1012154899Srik len = m_length (m, NULL); 1013154899Srik#else 1014154899Srik len = m->m_pkthdr.len; 1015154899Srik#endif 1016154899Srik if (len >= BUFSZ) 1017154899Srik printf ("%s: too long packet: %d bytes: ", 1018154899Srik d->name, len); 1019154899Srik else if (! m->m_next) 1020154899Srik ce_send_packet (d->chan, (u_char*) mtod (m, caddr_t), len, 0); 1021154899Srik else { 1022154899Srik ce_buf_item_t *item = (ce_buf_item_t*)d->chan->tx_queue; 1023154899Srik m_copydata (m, 0, len, item->buf); 1024154899Srik ce_send_packet (d->chan, item->buf, len, 0); 1025154899Srik } 1026154899Srik m_freem (m); 1027154899Srik /* Set up transmit timeout, if the transmit ring is not empty.*/ 1028154899Srik d->timeout = 10; 1029154899Srik } 1030154899Srik#ifndef NETGRAPH 1031154899Srik#if __FreeBSD_version >= 600034 1032154899Srik d->ifp->if_flags |= IFF_DRV_OACTIVE; 1033154899Srik#else 1034154899Srik d->ifp->if_flags |= IFF_OACTIVE; 1035154899Srik#endif 1036154899Srik#endif 1037154899Srik} 1038154899Srik 1039154899Srik/* 1040154899Srik * Start output on the interface. 1041154899Srik * Always called on splimp(). 1042154899Srik */ 1043154899Srikstatic void ce_start (drv_t *d) 1044154899Srik{ 1045154899Srik if (d->running) { 1046154899Srik if (! d->chan->dtr) 1047154899Srik ce_set_dtr (d->chan, 1); 1048154899Srik if (! d->chan->rts) 1049154899Srik ce_set_rts (d->chan, 1); 1050154899Srik ce_send (d); 1051199407Sjhb callout_reset (&d->timeout_handle, hz, ce_watchdog_timer, d); 1052154899Srik } 1053154899Srik} 1054154899Srik 1055154899Srik/* 1056154899Srik * Handle transmit timeouts. 1057154899Srik * Recover after lost transmit interrupts. 1058154899Srik * Always called on splimp(). 1059154899Srik */ 1060154899Srikstatic void ce_watchdog (drv_t *d) 1061154899Srik{ 1062154899Srik CE_DEBUG (d, ("device timeout\n")); 1063154899Srik if (d->running) { 1064154899Srik ce_set_dtr (d->chan, 0); 1065154899Srik ce_set_rts (d->chan, 0); 1066154899Srik/* ce_stop_chan (d->chan);*/ 1067154899Srik/* ce_start_chan (d->chan, 1, 1, 0, 0);*/ 1068154899Srik ce_set_dtr (d->chan, 1); 1069154899Srik ce_set_rts (d->chan, 1); 1070154899Srik ce_start (d); 1071154899Srik } 1072154899Srik} 1073154899Srik 1074199407Sjhbstatic void ce_watchdog_timer (void *arg) 1075199407Sjhb{ 1076199407Sjhb drv_t *d = arg; 1077199407Sjhb bdrv_t *bd = d->board->sys; 1078199407Sjhb 1079199407Sjhb CE_LOCK(bd); 1080199407Sjhb if (d->timeout == 1) 1081199407Sjhb ce_watchdog (d); 1082199407Sjhb if (d->timeout) 1083199407Sjhb d->timeout--; 1084199407Sjhb callout_reset (&d->timeout_handle, hz, ce_watchdog_timer, d); 1085199407Sjhb CE_UNLOCK(bd); 1086199407Sjhb} 1087199407Sjhb 1088154899Srikstatic void ce_transmit (ce_chan_t *c, void *attachment, int len) 1089154899Srik{ 1090154899Srik drv_t *d = c->sys; 1091154899Srik 1092154899Srik d->timeout = 0; 1093199407Sjhb#ifndef NETGRAPH 1094271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_OPACKETS, 1); 1095154899Srik#if __FreeBSD_version >= 600034 1096154899Srik d->ifp->if_flags &= ~IFF_DRV_OACTIVE; 1097154899Srik#else 1098154899Srik d->ifp->if_flags &= ~IFF_OACTIVE; 1099154899Srik#endif 1100154899Srik#endif 1101154899Srik ce_start (d); 1102154899Srik} 1103154899Srik 1104154899Srikstatic void ce_receive (ce_chan_t *c, unsigned char *data, int len) 1105154899Srik{ 1106154899Srik drv_t *d = c->sys; 1107154899Srik struct mbuf *m; 1108154899Srik 1109154899Srik if (! d->running) 1110154899Srik return; 1111154899Srik 1112154899Srik m = makembuf (data, len); 1113154899Srik if (! m) { 1114154899Srik CE_DEBUG (d, ("no memory for packet\n")); 1115154899Srik#ifndef NETGRAPH 1116271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_IQDROPS, 1); 1117154899Srik#endif 1118154899Srik return; 1119154899Srik } 1120154899Srik if (c->debug > 1) 1121271373Srwatson m_print (m, 0); 1122154899Srik#ifdef NETGRAPH 1123154899Srik m->m_pkthdr.rcvif = 0; 1124154899Srik IF_ENQUEUE(&d->rqueue, m); 1125154899Srik#else 1126271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_IPACKETS, 1); 1127154899Srik m->m_pkthdr.rcvif = d->ifp; 1128154899Srik /* Check if there's a BPF listener on this interface. 1129154899Srik * If so, hand off the raw packet to bpf. */ 1130272266Smelifaro BPF_MTAP(d->ifp, m); 1131154899Srik IF_ENQUEUE(&d->rqueue, m); 1132154899Srik#endif 1133154899Srik} 1134154899Srik 1135154899Srikstatic void ce_error (ce_chan_t *c, int data) 1136154899Srik{ 1137154899Srik drv_t *d = c->sys; 1138154899Srik 1139154899Srik switch (data) { 1140154899Srik case CE_FRAME: 1141154899Srik CE_DEBUG (d, ("frame error\n")); 1142154899Srik#ifndef NETGRAPH 1143271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); 1144154899Srik#endif 1145154899Srik break; 1146154899Srik case CE_CRC: 1147154899Srik CE_DEBUG (d, ("crc error\n")); 1148154899Srik#ifndef NETGRAPH 1149271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); 1150154899Srik#endif 1151154899Srik break; 1152154899Srik case CE_OVERRUN: 1153154899Srik CE_DEBUG (d, ("overrun error\n")); 1154154899Srik#ifndef NETGRAPH 1155271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_COLLISIONS, 1); 1156271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); 1157154899Srik#endif 1158154899Srik break; 1159154899Srik case CE_OVERFLOW: 1160154899Srik CE_DEBUG (d, ("overflow error\n")); 1161154899Srik#ifndef NETGRAPH 1162271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); 1163154899Srik#endif 1164154899Srik break; 1165154899Srik case CE_UNDERRUN: 1166154899Srik CE_DEBUG (d, ("underrun error\n")); 1167154899Srik d->timeout = 0; 1168199407Sjhb#ifndef NETGRAPH 1169271849Sglebius if_inc_counter(d->ifp, IFCOUNTER_OERRORS, 1); 1170154899Srik#if __FreeBSD_version >= 600034 1171154899Srik d->ifp->if_flags &= ~IFF_DRV_OACTIVE; 1172154899Srik#else 1173154899Srik d->ifp->if_flags &= ~IFF_OACTIVE; 1174154899Srik#endif 1175154899Srik#endif 1176154899Srik ce_start (d); 1177154899Srik break; 1178154899Srik default: 1179154899Srik CE_DEBUG (d, ("error #%d\n", data)); 1180154899Srik break; 1181154899Srik } 1182154899Srik} 1183154899Srik 1184154899Srik/* 1185154899Srik * You also need read, write, open, close routines. 1186154899Srik * This should get you started 1187154899Srik */ 1188154899Srik#if __FreeBSD_version < 500000 1189154899Srikstatic int ce_open (dev_t dev, int oflags, int devtype, struct proc *p) 1190154899Srik#else 1191154899Srikstatic int ce_open (struct cdev *dev, int oflags, int devtype, struct thread *td) 1192154899Srik#endif 1193154899Srik{ 1194183397Sed int unit = dev2unit (dev); 1195154899Srik drv_t *d; 1196154899Srik 1197154899Srik if (unit >= NBRD*NCHAN || ! (d = channel[unit])) 1198154899Srik return ENXIO; 1199154899Srik CE_DEBUG2 (d, ("ce_open\n")); 1200154899Srik return 0; 1201154899Srik} 1202154899Srik 1203154899Srik/* 1204154899Srik * Only called on the LAST close. 1205154899Srik */ 1206154899Srik#if __FreeBSD_version < 500000 1207154899Srikstatic int ce_close (dev_t dev, int fflag, int devtype, struct proc *p) 1208154899Srik#else 1209154899Srikstatic int ce_close (struct cdev *dev, int fflag, int devtype, struct thread *td) 1210154899Srik#endif 1211154899Srik{ 1212183397Sed drv_t *d = channel [dev2unit (dev)]; 1213154899Srik 1214154899Srik CE_DEBUG2 (d, ("ce_close\n")); 1215154899Srik return 0; 1216154899Srik} 1217154899Srik 1218154899Srikstatic int ce_modem_status (ce_chan_t *c) 1219154899Srik{ 1220154899Srik drv_t *d = c->sys; 1221154899Srik bdrv_t *bd = d->board->sys; 1222154899Srik int status, s; 1223154899Srik 1224154899Srik status = d->running ? TIOCM_LE : 0; 1225154899Srik s = splimp (); 1226154899Srik CE_LOCK (bd); 1227154899Srik if (ce_get_cd (c)) status |= TIOCM_CD; 1228154899Srik if (ce_get_cts (c)) status |= TIOCM_CTS; 1229154899Srik if (ce_get_dsr (c)) status |= TIOCM_DSR; 1230154899Srik if (c->dtr) status |= TIOCM_DTR; 1231154899Srik if (c->rts) status |= TIOCM_RTS; 1232154899Srik CE_UNLOCK (bd); 1233154899Srik splx (s); 1234154899Srik return status; 1235154899Srik} 1236154899Srik 1237154899Srik#if __FreeBSD_version < 500000 1238154899Srikstatic int ce_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 1239154899Srik#else 1240154899Srikstatic int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 1241154899Srik#endif 1242154899Srik{ 1243183397Sed drv_t *d = channel [dev2unit (dev)]; 1244154899Srik bdrv_t *bd = d->board->sys; 1245154899Srik ce_chan_t *c = d->chan; 1246154899Srik struct serial_statistics *st; 1247154899Srik struct e1_statistics *opte1; 1248154899Srik int error, s; 1249154899Srik char mask[16]; 1250154899Srik 1251154899Srik switch (cmd) { 1252154899Srik case SERIAL_GETREGISTERED: 1253154899Srik CE_DEBUG2 (d, ("ioctl: getregistered\n")); 1254154899Srik bzero (mask, sizeof(mask)); 1255154899Srik for (s=0; s<NBRD*NCHAN; ++s) 1256154899Srik if (channel [s]) 1257154899Srik mask [s/8] |= 1 << (s & 7); 1258154899Srik bcopy (mask, data, sizeof (mask)); 1259154899Srik return 0; 1260154899Srik 1261154899Srik#ifndef NETGRAPH 1262154899Srik case SERIAL_GETPROTO: 1263154899Srik CE_DEBUG2 (d, ("ioctl: getproto\n")); 1264154899Srik strcpy ((char*)data, (IFP2SP(d->ifp)->pp_flags & PP_FR) ? "fr" : 1265154899Srik (d->ifp->if_flags & PP_CISCO) ? "cisco" : "ppp"); 1266154899Srik return 0; 1267154899Srik 1268154899Srik case SERIAL_SETPROTO: 1269154899Srik CE_DEBUG2 (d, ("ioctl: setproto\n")); 1270154899Srik /* Only for superuser! */ 1271154899Srik#if __FreeBSD_version < 500000 1272154899Srik error = suser (p); 1273180147Sdds#elif __FreeBSD_version < 700000 1274154899Srik error = suser (td); 1275164033Srwatson#else 1276164033Srwatson error = priv_check (td, PRIV_DRIVER); 1277164033Srwatson#endif 1278154899Srik if (error) 1279154899Srik return error; 1280154899Srik#if __FreeBSD_version >= 600034 1281154899Srik if (d->ifp->if_flags & IFF_DRV_RUNNING) 1282154899Srik#else 1283154899Srik if (d->ifp->if_flags & IFF_RUNNING) 1284154899Srik#endif 1285154899Srik return EBUSY; 1286154899Srik if (! strcmp ("cisco", (char*)data)) { 1287154899Srik IFP2SP(d->ifp)->pp_flags &= ~(PP_FR); 1288154899Srik IFP2SP(d->ifp)->pp_flags |= PP_KEEPALIVE; 1289154899Srik d->ifp->if_flags |= PP_CISCO; 1290228963Sdim#if PP_FR != 0 1291228963Sdim } else if (! strcmp ("fr", (char*)data)) { 1292154899Srik d->ifp->if_flags &= ~(PP_CISCO); 1293154899Srik IFP2SP(d->ifp)->pp_flags |= PP_FR | PP_KEEPALIVE; 1294228963Sdim#endif 1295154899Srik } else if (! strcmp ("ppp", (char*)data)) { 1296154899Srik IFP2SP(d->ifp)->pp_flags &= ~PP_FR; 1297154899Srik IFP2SP(d->ifp)->pp_flags &= ~PP_KEEPALIVE; 1298154899Srik d->ifp->if_flags &= ~(PP_CISCO); 1299154899Srik } else 1300154899Srik return EINVAL; 1301154899Srik return 0; 1302154899Srik 1303154899Srik case SERIAL_GETKEEPALIVE: 1304154899Srik CE_DEBUG2 (d, ("ioctl: getkeepalive\n")); 1305154899Srik if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || 1306154899Srik (d->ifp->if_flags & PP_CISCO)) 1307154899Srik return EINVAL; 1308154899Srik *(int*)data = (IFP2SP(d->ifp)->pp_flags & PP_KEEPALIVE) ? 1 : 0; 1309154899Srik return 0; 1310154899Srik 1311154899Srik case SERIAL_SETKEEPALIVE: 1312154899Srik CE_DEBUG2 (d, ("ioctl: setkeepalive\n")); 1313154899Srik /* Only for superuser! */ 1314154899Srik#if __FreeBSD_version < 500000 1315154899Srik error = suser (p); 1316180147Sdds#elif __FreeBSD_version < 700000 1317164033Srwatson error = suser (td); 1318154899Srik#else 1319164033Srwatson error = priv_check (td, PRIV_DRIVER); 1320154899Srik#endif 1321154899Srik if (error) 1322154899Srik return error; 1323154899Srik if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || 1324154899Srik (d->ifp->if_flags & PP_CISCO)) 1325154899Srik return EINVAL; 1326154899Srik s = splimp (); 1327154899Srik CE_LOCK (bd); 1328154899Srik if (*(int*)data) 1329154899Srik IFP2SP(d->ifp)->pp_flags |= PP_KEEPALIVE; 1330154899Srik else 1331154899Srik IFP2SP(d->ifp)->pp_flags &= ~PP_KEEPALIVE; 1332154899Srik CE_UNLOCK (bd); 1333154899Srik splx (s); 1334154899Srik return 0; 1335154899Srik#endif /*NETGRAPH*/ 1336154899Srik 1337154899Srik case SERIAL_GETMODE: 1338154899Srik CE_DEBUG2 (d, ("ioctl: getmode\n")); 1339154899Srik *(int*)data = SERIAL_HDLC; 1340154899Srik return 0; 1341154899Srik 1342154899Srik case SERIAL_SETMODE: 1343154899Srik /* Only for superuser! */ 1344154899Srik#if __FreeBSD_version < 500000 1345154899Srik error = suser (p); 1346180147Sdds#elif __FreeBSD_version < 700000 1347164033Srwatson error = suser (td); 1348154899Srik#else 1349164033Srwatson error = priv_check (td, PRIV_DRIVER); 1350154899Srik#endif 1351154899Srik if (error) 1352154899Srik return error; 1353154899Srik if (*(int*)data != SERIAL_HDLC) 1354154899Srik return EINVAL; 1355154899Srik return 0; 1356154899Srik 1357154899Srik case SERIAL_GETCFG: 1358154899Srik CE_DEBUG2 (d, ("ioctl: getcfg\n")); 1359154899Srik *(char*)data = 'c'; 1360154899Srik return 0; 1361154899Srik 1362154899Srik case SERIAL_SETCFG: 1363154899Srik CE_DEBUG2 (d, ("ioctl: setcfg\n")); 1364154899Srik#if __FreeBSD_version < 500000 1365154899Srik error = suser (p); 1366180147Sdds#elif __FreeBSD_version < 700000 1367164033Srwatson error = suser (td); 1368154899Srik#else 1369164033Srwatson error = priv_check (td, PRIV_DRIVER); 1370154899Srik#endif 1371154899Srik if (error) 1372154899Srik return error; 1373154899Srik if (*((char*)data) != 'c') 1374154899Srik return EINVAL; 1375154899Srik return 0; 1376154899Srik 1377154899Srik case SERIAL_GETSTAT: 1378154899Srik CE_DEBUG2 (d, ("ioctl: getstat\n")); 1379154899Srik st = (struct serial_statistics*) data; 1380154899Srik st->rintr = c->rintr; 1381154899Srik st->tintr = c->tintr; 1382154899Srik st->mintr = 0; 1383154899Srik st->ibytes = c->ibytes; 1384154899Srik st->ipkts = c->ipkts; 1385154899Srik st->obytes = c->obytes; 1386154899Srik st->opkts = c->opkts; 1387154899Srik st->ierrs = c->overrun + c->frame + c->crc; 1388154899Srik st->oerrs = c->underrun; 1389154899Srik return 0; 1390154899Srik 1391154899Srik case SERIAL_GETESTAT: 1392154899Srik CE_DEBUG2 (d, ("ioctl: getestat\n")); 1393154899Srik if (c->type != T_E1) 1394154899Srik return EINVAL; 1395154899Srik opte1 = (struct e1_statistics*) data; 1396154899Srik 1397154899Srik opte1->status = 0; 1398154899Srik if (c->status & ESTS_NOALARM) 1399154899Srik opte1->status |= E1_NOALARM; 1400154899Srik if (c->status & ESTS_LOS) 1401154899Srik opte1->status |= E1_LOS; 1402154899Srik if (c->status & ESTS_LOF) 1403154899Srik opte1->status |= E1_LOF; 1404154899Srik if (c->status & ESTS_AIS) 1405154899Srik opte1->status |= E1_AIS; 1406154899Srik if (c->status & ESTS_LOMF) 1407154899Srik opte1->status |= E1_LOMF; 1408154899Srik if (c->status & ESTS_AIS16) 1409154899Srik opte1->status |= E1_AIS16; 1410154899Srik if (c->status & ESTS_FARLOF) 1411154899Srik opte1->status |= E1_FARLOF; 1412154899Srik if (c->status & ESTS_FARLOMF) 1413154899Srik opte1->status |= E1_FARLOMF; 1414154899Srik if (c->status & ESTS_TSTREQ) 1415154899Srik opte1->status |= E1_TSTREQ; 1416154899Srik if (c->status & ESTS_TSTERR) 1417154899Srik opte1->status |= E1_TSTERR; 1418154899Srik 1419154899Srik opte1->cursec = c->cursec; 1420154899Srik opte1->totsec = c->totsec + c->cursec; 1421154899Srik 1422154899Srik opte1->currnt.bpv = c->currnt.bpv; 1423154899Srik opte1->currnt.fse = c->currnt.fse; 1424154899Srik opte1->currnt.crce = c->currnt.crce; 1425154899Srik opte1->currnt.rcrce = c->currnt.rcrce; 1426154899Srik opte1->currnt.uas = c->currnt.uas; 1427154899Srik opte1->currnt.les = c->currnt.les; 1428154899Srik opte1->currnt.es = c->currnt.es; 1429154899Srik opte1->currnt.bes = c->currnt.bes; 1430154899Srik opte1->currnt.ses = c->currnt.ses; 1431154899Srik opte1->currnt.oofs = c->currnt.oofs; 1432154899Srik opte1->currnt.css = c->currnt.css; 1433154899Srik opte1->currnt.dm = c->currnt.dm; 1434154899Srik 1435154899Srik opte1->total.bpv = c->total.bpv + c->currnt.bpv; 1436154899Srik opte1->total.fse = c->total.fse + c->currnt.fse; 1437154899Srik opte1->total.crce = c->total.crce + c->currnt.crce; 1438154899Srik opte1->total.rcrce = c->total.rcrce + c->currnt.rcrce; 1439154899Srik opte1->total.uas = c->total.uas + c->currnt.uas; 1440154899Srik opte1->total.les = c->total.les + c->currnt.les; 1441154899Srik opte1->total.es = c->total.es + c->currnt.es; 1442154899Srik opte1->total.bes = c->total.bes + c->currnt.bes; 1443154899Srik opte1->total.ses = c->total.ses + c->currnt.ses; 1444154899Srik opte1->total.oofs = c->total.oofs + c->currnt.oofs; 1445154899Srik opte1->total.css = c->total.css + c->currnt.css; 1446154899Srik opte1->total.dm = c->total.dm + c->currnt.dm; 1447154899Srik for (s=0; s<48; ++s) { 1448154899Srik opte1->interval[s].bpv = c->interval[s].bpv; 1449154899Srik opte1->interval[s].fse = c->interval[s].fse; 1450154899Srik opte1->interval[s].crce = c->interval[s].crce; 1451154899Srik opte1->interval[s].rcrce = c->interval[s].rcrce; 1452154899Srik opte1->interval[s].uas = c->interval[s].uas; 1453154899Srik opte1->interval[s].les = c->interval[s].les; 1454154899Srik opte1->interval[s].es = c->interval[s].es; 1455154899Srik opte1->interval[s].bes = c->interval[s].bes; 1456154899Srik opte1->interval[s].ses = c->interval[s].ses; 1457154899Srik opte1->interval[s].oofs = c->interval[s].oofs; 1458154899Srik opte1->interval[s].css = c->interval[s].css; 1459154899Srik opte1->interval[s].dm = c->interval[s].dm; 1460154899Srik } 1461154899Srik return 0; 1462154899Srik 1463154899Srik case SERIAL_CLRSTAT: 1464154899Srik CE_DEBUG2 (d, ("ioctl: clrstat\n")); 1465154899Srik /* Only for superuser! */ 1466154899Srik#if __FreeBSD_version < 500000 1467154899Srik error = suser (p); 1468180147Sdds#elif __FreeBSD_version < 700000 1469164033Srwatson error = suser (td); 1470154899Srik#else 1471164033Srwatson error = priv_check (td, PRIV_DRIVER); 1472154899Srik#endif 1473154899Srik if (error) 1474154899Srik return error; 1475154899Srik c->rintr = 0; 1476154899Srik c->tintr = 0; 1477154899Srik c->ibytes = 0; 1478154899Srik c->obytes = 0; 1479154899Srik c->ipkts = 0; 1480154899Srik c->opkts = 0; 1481154899Srik c->overrun = 0; 1482154899Srik c->frame = 0; 1483154899Srik c->crc = 0; 1484154899Srik c->underrun = 0; 1485154899Srik bzero (&c->currnt, sizeof (c->currnt)); 1486154899Srik bzero (&c->total, sizeof (c->total)); 1487154899Srik bzero (c->interval, sizeof (c->interval)); 1488154899Srik return 0; 1489154899Srik 1490154899Srik case SERIAL_GETLOOP: 1491154899Srik CE_DEBUG2 (d, ("ioctl: getloop\n")); 1492154899Srik if (c->type != T_E1) 1493154899Srik return EINVAL; 1494154899Srik *(int*)data = c->lloop; 1495154899Srik return 0; 1496154899Srik 1497154899Srik case SERIAL_SETLOOP: 1498154899Srik CE_DEBUG2 (d, ("ioctl: setloop\n")); 1499154899Srik if (c->type != T_E1) 1500154899Srik return EINVAL; 1501154899Srik /* Only for superuser! */ 1502154899Srik#if __FreeBSD_version < 500000 1503154899Srik error = suser (p); 1504180147Sdds#elif __FreeBSD_version < 700000 1505164033Srwatson error = suser (td); 1506154899Srik#else 1507164033Srwatson error = priv_check (td, PRIV_DRIVER); 1508154899Srik#endif 1509154899Srik if (error) 1510154899Srik return error; 1511154899Srik s = splimp (); 1512154899Srik CE_LOCK (bd); 1513154899Srik ce_set_lloop (c, *(int*)data); 1514154899Srik CE_UNLOCK (bd); 1515154899Srik splx (s); 1516154899Srik return 0; 1517154899Srik 1518154899Srik case SERIAL_GETRLOOP: 1519154899Srik CE_DEBUG2 (d, ("ioctl: getrloop\n")); 1520154899Srik if (c->type != T_E1) 1521154899Srik return EINVAL; 1522154899Srik *(int*)data = c->rloop; 1523154899Srik return 0; 1524154899Srik 1525154899Srik case SERIAL_SETRLOOP: 1526154899Srik CE_DEBUG2 (d, ("ioctl: setloop\n")); 1527154899Srik if (c->type != T_E1) 1528154899Srik return EINVAL; 1529154899Srik /* Only for superuser! */ 1530154899Srik#if __FreeBSD_version < 500000 1531154899Srik error = suser (p); 1532180147Sdds#elif __FreeBSD_version < 700000 1533164033Srwatson error = suser (td); 1534154899Srik#else 1535164033Srwatson error = priv_check (td, PRIV_DRIVER); 1536154899Srik#endif 1537154899Srik if (error) 1538154899Srik return error; 1539154899Srik s = splimp (); 1540154899Srik CE_LOCK (bd); 1541154899Srik ce_set_rloop (c, *(int*)data); 1542154899Srik CE_UNLOCK (bd); 1543154899Srik splx (s); 1544154899Srik return 0; 1545154899Srik 1546154899Srik case SERIAL_GETDEBUG: 1547154899Srik CE_DEBUG2 (d, ("ioctl: getdebug\n")); 1548154899Srik *(int*)data = d->chan->debug; 1549154899Srik return 0; 1550154899Srik 1551154899Srik case SERIAL_SETDEBUG: 1552154899Srik CE_DEBUG2 (d, ("ioctl: setdebug\n")); 1553154899Srik /* Only for superuser! */ 1554154899Srik#if __FreeBSD_version < 500000 1555154899Srik error = suser (p); 1556180147Sdds#elif __FreeBSD_version < 700000 1557164033Srwatson error = suser (td); 1558154899Srik#else 1559164033Srwatson error = priv_check (td, PRIV_DRIVER); 1560154899Srik#endif 1561154899Srik if (error) 1562154899Srik return error; 1563180132Srik#ifndef NETGRAPH 1564180132Srik /* 1565180132Srik * The debug_shadow is always greater than zero for logic 1566180132Srik * simplicity. For switching debug off the IFF_DEBUG is 1567180132Srik * responsible. 1568180132Srik */ 1569180132Srik d->chan->debug_shadow = (*(int*)data) ? (*(int*)data) : 1; 1570180132Srik if (d->ifp->if_flags & IFF_DEBUG) 1571180132Srik d->chan->debug = d->chan->debug_shadow; 1572180132Srik#else 1573154899Srik d->chan->debug = *(int*)data; 1574154899Srik#endif 1575154899Srik return 0; 1576154899Srik 1577154899Srik case SERIAL_GETBAUD: 1578154899Srik CE_DEBUG2 (d, ("ioctl: getbaud\n")); 1579154899Srik *(long*)data = c->baud; 1580154899Srik return 0; 1581154899Srik 1582154899Srik case SERIAL_SETBAUD: 1583154899Srik CE_DEBUG2 (d, ("ioctl: setbaud\n")); 1584154899Srik if (c->type != T_E1 || !c->unfram) 1585154899Srik return EINVAL; 1586154899Srik /* Only for superuser! */ 1587154899Srik#if __FreeBSD_version < 500000 1588154899Srik error = suser (p); 1589180147Sdds#elif __FreeBSD_version < 700000 1590164033Srwatson error = suser (td); 1591154899Srik#else 1592164033Srwatson error = priv_check (td, PRIV_DRIVER); 1593154899Srik#endif 1594154899Srik if (error) 1595154899Srik return error; 1596154899Srik s = splimp (); 1597154899Srik CE_LOCK (bd); 1598154899Srik ce_set_baud (c, *(long*)data); 1599154899Srik CE_UNLOCK (bd); 1600154899Srik splx (s); 1601154899Srik return 0; 1602154899Srik 1603154899Srik case SERIAL_GETTIMESLOTS: 1604154899Srik CE_DEBUG2 (d, ("ioctl: gettimeslots\n")); 1605154899Srik if ((c->type != T_E1 || c->unfram) && c->type != T_DATA) 1606154899Srik return EINVAL; 1607154899Srik *(u_long*)data = c->ts; 1608154899Srik return 0; 1609154899Srik 1610154899Srik case SERIAL_SETTIMESLOTS: 1611154899Srik CE_DEBUG2 (d, ("ioctl: settimeslots\n")); 1612154899Srik /* Only for superuser! */ 1613154899Srik#if __FreeBSD_version < 500000 1614154899Srik error = suser (p); 1615180147Sdds#elif __FreeBSD_version < 700000 1616164033Srwatson error = suser (td); 1617154899Srik#else 1618164033Srwatson error = priv_check (td, PRIV_DRIVER); 1619154899Srik#endif 1620154899Srik if (error) 1621154899Srik return error; 1622154899Srik if ((c->type != T_E1 || c->unfram) && c->type != T_DATA) 1623154899Srik return EINVAL; 1624154899Srik s = splimp (); 1625154899Srik CE_LOCK (bd); 1626154899Srik ce_set_ts (c, *(u_long*)data); 1627154899Srik CE_UNLOCK (bd); 1628154899Srik splx (s); 1629154899Srik return 0; 1630154899Srik 1631154899Srik case SERIAL_GETHIGAIN: 1632154899Srik CE_DEBUG2 (d, ("ioctl: gethigain\n")); 1633154899Srik if (c->type != T_E1) 1634154899Srik return EINVAL; 1635154899Srik *(int*)data = c->higain; 1636154899Srik return 0; 1637154899Srik 1638154899Srik case SERIAL_SETHIGAIN: 1639154899Srik CE_DEBUG2 (d, ("ioctl: sethigain\n")); 1640154899Srik if (c->type != T_E1) 1641154899Srik return EINVAL; 1642154899Srik /* Only for superuser! */ 1643154899Srik#if __FreeBSD_version < 500000 1644154899Srik error = suser (p); 1645180147Sdds#elif __FreeBSD_version < 700000 1646164033Srwatson error = suser (td); 1647154899Srik#else 1648164033Srwatson error = priv_check (td, PRIV_DRIVER); 1649154899Srik#endif 1650154899Srik if (error) 1651154899Srik return error; 1652154899Srik s = splimp (); 1653154899Srik CE_LOCK (bd); 1654154899Srik ce_set_higain (c, *(int*)data); 1655154899Srik CE_UNLOCK (bd); 1656154899Srik splx (s); 1657154899Srik return 0; 1658154899Srik 1659154899Srik case SERIAL_GETPHONY: 1660154899Srik CE_DEBUG2 (d, ("ioctl: getphony\n")); 1661154899Srik *(int*)data = c->phony; 1662154899Srik return 0; 1663154899Srik 1664154899Srik case SERIAL_SETPHONY: 1665154899Srik CE_DEBUG2 (d, ("ioctl: setphony\n")); 1666154899Srik /* Only for superuser! */ 1667154899Srik#if __FreeBSD_version < 500000 1668154899Srik error = suser (p); 1669180147Sdds#elif __FreeBSD_version < 700000 1670164033Srwatson error = suser (td); 1671154899Srik#else 1672164033Srwatson error = priv_check (td, PRIV_DRIVER); 1673154899Srik#endif 1674154899Srik if (error) 1675154899Srik return error; 1676154899Srik s = splimp (); 1677154899Srik CE_LOCK (bd); 1678154899Srik ce_set_phony (c, *(int*)data); 1679154899Srik CE_UNLOCK (bd); 1680154899Srik splx (s); 1681154899Srik return 0; 1682154899Srik 1683154899Srik case SERIAL_GETUNFRAM: 1684154899Srik CE_DEBUG2 (d, ("ioctl: getunfram\n")); 1685154899Srik if (c->type != T_E1 || c->num != 0) 1686154899Srik return EINVAL; 1687154899Srik *(int*)data = c->unfram; 1688154899Srik return 0; 1689154899Srik 1690154899Srik case SERIAL_SETUNFRAM: 1691154899Srik CE_DEBUG2 (d, ("ioctl: setunfram\n")); 1692154899Srik if (c->type != T_E1 || c->num != 0) 1693154899Srik return EINVAL; 1694154899Srik /* Only for superuser! */ 1695154899Srik#if __FreeBSD_version < 500000 1696154899Srik error = suser (p); 1697180147Sdds#elif __FreeBSD_version < 700000 1698164033Srwatson error = suser (td); 1699154899Srik#else 1700164033Srwatson error = priv_check (td, PRIV_DRIVER); 1701154899Srik#endif 1702154899Srik if (error) 1703154899Srik return error; 1704154899Srik s = splimp (); 1705154899Srik CE_LOCK (bd); 1706154899Srik ce_set_unfram (c, *(int*)data); 1707154899Srik CE_UNLOCK (bd); 1708154899Srik splx (s); 1709154899Srik return 0; 1710154899Srik 1711154899Srik case SERIAL_GETSCRAMBLER: 1712154899Srik CE_DEBUG2 (d, ("ioctl: getscrambler\n")); 1713154899Srik if (!c->unfram) 1714154899Srik return EINVAL; 1715154899Srik *(int*)data = c->scrambler; 1716154899Srik return 0; 1717154899Srik 1718154899Srik case SERIAL_SETSCRAMBLER: 1719154899Srik CE_DEBUG2 (d, ("ioctl: setscrambler\n")); 1720154899Srik /* Only for superuser! */ 1721154899Srik#if __FreeBSD_version < 500000 1722154899Srik error = suser (p); 1723180147Sdds#elif __FreeBSD_version < 700000 1724164033Srwatson error = suser (td); 1725154899Srik#else 1726164033Srwatson error = priv_check (td, PRIV_DRIVER); 1727154899Srik#endif 1728154899Srik if (error) 1729154899Srik return error; 1730154899Srik if (!c->unfram) 1731154899Srik return EINVAL; 1732154899Srik s = splimp (); 1733154899Srik CE_LOCK (bd); 1734154899Srik ce_set_scrambler (c, *(int*)data); 1735154899Srik CE_UNLOCK (bd); 1736154899Srik splx (s); 1737154899Srik return 0; 1738154899Srik 1739154899Srik case SERIAL_GETMONITOR: 1740154899Srik CE_DEBUG2 (d, ("ioctl: getmonitor\n")); 1741154899Srik if (c->type != T_E1) 1742154899Srik return EINVAL; 1743154899Srik *(int*)data = c->monitor; 1744154899Srik return 0; 1745154899Srik 1746154899Srik case SERIAL_SETMONITOR: 1747154899Srik CE_DEBUG2 (d, ("ioctl: setmonitor\n")); 1748154899Srik /* Only for superuser! */ 1749154899Srik#if __FreeBSD_version < 500000 1750154899Srik error = suser (p); 1751180147Sdds#elif __FreeBSD_version < 700000 1752164033Srwatson error = suser (td); 1753154899Srik#else 1754164033Srwatson error = priv_check (td, PRIV_DRIVER); 1755154899Srik#endif 1756154899Srik if (error) 1757154899Srik return error; 1758154899Srik if (c->type != T_E1) 1759154899Srik return EINVAL; 1760154899Srik s = splimp (); 1761154899Srik CE_LOCK (bd); 1762154899Srik ce_set_monitor (c, *(int*)data); 1763154899Srik CE_UNLOCK (bd); 1764154899Srik splx (s); 1765154899Srik return 0; 1766154899Srik 1767154899Srik case SERIAL_GETUSE16: 1768154899Srik CE_DEBUG2 (d, ("ioctl: getuse16\n")); 1769154899Srik if (c->type != T_E1 || c->unfram) 1770154899Srik return EINVAL; 1771154899Srik *(int*)data = c->use16; 1772154899Srik return 0; 1773154899Srik 1774154899Srik case SERIAL_SETUSE16: 1775154899Srik CE_DEBUG2 (d, ("ioctl: setuse16\n")); 1776154899Srik /* Only for superuser! */ 1777154899Srik#if __FreeBSD_version < 500000 1778154899Srik error = suser (p); 1779180147Sdds#elif __FreeBSD_version < 700000 1780164033Srwatson error = suser (td); 1781154899Srik#else 1782164033Srwatson error = priv_check (td, PRIV_DRIVER); 1783154899Srik#endif 1784154899Srik if (error) 1785154899Srik return error; 1786154899Srik if (c->type != T_E1) 1787154899Srik return EINVAL; 1788154899Srik s = splimp (); 1789154899Srik CE_LOCK (bd); 1790154899Srik ce_set_use16 (c, *(int*)data); 1791154899Srik CE_UNLOCK (bd); 1792154899Srik splx (s); 1793154899Srik return 0; 1794154899Srik 1795154899Srik case SERIAL_GETCRC4: 1796154899Srik CE_DEBUG2 (d, ("ioctl: getcrc4\n")); 1797154899Srik if (c->type != T_E1 || c->unfram) 1798154899Srik return EINVAL; 1799154899Srik *(int*)data = c->crc4; 1800154899Srik return 0; 1801154899Srik 1802154899Srik case SERIAL_SETCRC4: 1803154899Srik CE_DEBUG2 (d, ("ioctl: setcrc4\n")); 1804154899Srik /* Only for superuser! */ 1805154899Srik#if __FreeBSD_version < 500000 1806154899Srik error = suser (p); 1807180147Sdds#elif __FreeBSD_version < 700000 1808164033Srwatson error = suser (td); 1809154899Srik#else 1810164033Srwatson error = priv_check (td, PRIV_DRIVER); 1811154899Srik#endif 1812154899Srik if (error) 1813154899Srik return error; 1814154899Srik if (c->type != T_E1 || c->unfram) 1815154899Srik return EINVAL; 1816154899Srik s = splimp (); 1817154899Srik CE_LOCK (bd); 1818154899Srik ce_set_crc4 (c, *(int*)data); 1819154899Srik CE_UNLOCK (bd); 1820154899Srik splx (s); 1821154899Srik return 0; 1822154899Srik 1823154899Srik case SERIAL_GETCLK: 1824154899Srik CE_DEBUG2 (d, ("ioctl: getclk\n")); 1825154899Srik if (c->type != T_E1) 1826154899Srik return EINVAL; 1827154899Srik switch (c->gsyn) { 1828154899Srik default: *(int*)data = E1CLK_INTERNAL; break; 1829154899Srik case GSYN_RCV: *(int*)data = E1CLK_RECEIVE; break; 1830154899Srik case GSYN_RCV0: *(int*)data = E1CLK_RECEIVE_CHAN0; break; 1831154899Srik case GSYN_RCV1: *(int*)data = E1CLK_RECEIVE_CHAN1; break; 1832154899Srik } 1833154899Srik return 0; 1834154899Srik 1835154899Srik case SERIAL_SETCLK: 1836154899Srik CE_DEBUG2 (d, ("ioctl: setclk\n")); 1837154899Srik /* Only for superuser! */ 1838154899Srik#if __FreeBSD_version < 500000 1839154899Srik error = suser (p); 1840180147Sdds#elif __FreeBSD_version < 700000 1841164033Srwatson error = suser (td); 1842154899Srik#else 1843164033Srwatson error = priv_check (td, PRIV_DRIVER); 1844154899Srik#endif 1845154899Srik if (error) 1846154899Srik return error; 1847154899Srik if (c->type != T_E1) 1848154899Srik return EINVAL; 1849154899Srik s = splimp (); 1850154899Srik CE_LOCK (bd); 1851154899Srik switch (*(int*)data) { 1852154899Srik default: ce_set_gsyn (c, GSYN_INT); break; 1853154899Srik case E1CLK_RECEIVE: ce_set_gsyn (c, GSYN_RCV); break; 1854154899Srik case E1CLK_RECEIVE_CHAN0: ce_set_gsyn (c, GSYN_RCV0); break; 1855154899Srik case E1CLK_RECEIVE_CHAN1: ce_set_gsyn (c, GSYN_RCV1); break; 1856154899Srik } 1857154899Srik CE_UNLOCK (bd); 1858154899Srik splx (s); 1859154899Srik return 0; 1860154899Srik 1861154899Srik#if 0 1862154899Srik case SERIAL_RESET: 1863154899Srik CE_DEBUG2 (d, ("ioctl: reset\n")); 1864154899Srik /* Only for superuser! */ 1865154899Srik#if __FreeBSD_version < 500000 1866154899Srik error = suser (p); 1867180147Sdds#elif __FreeBSD_version < 700000 1868164033Srwatson error = suser (td); 1869154899Srik#else 1870164033Srwatson error = priv_check (td, PRIV_DRIVER); 1871154899Srik#endif 1872154899Srik if (error) 1873154899Srik return error; 1874154899Srik s = splimp (); 1875154899Srik CE_LOCK (bd); 1876154899Srik/* ce_reset (c->board, 0, 0);*/ 1877154899Srik CE_UNLOCK (bd); 1878154899Srik splx (s); 1879154899Srik return 0; 1880154899Srik 1881154899Srik case SERIAL_HARDRESET: 1882154899Srik CE_DEBUG2 (d, ("ioctl: hardreset\n")); 1883154899Srik /* Only for superuser! */ 1884154899Srik#if __FreeBSD_version < 500000 1885154899Srik error = suser (p); 1886180147Sdds#elif __FreeBSD_version < 700000 1887164033Srwatson error = suser (td); 1888154899Srik#else 1889164033Srwatson error = priv_check (td, PRIV_DRIVER); 1890154899Srik#endif 1891154899Srik if (error) 1892154899Srik return error; 1893154899Srik s = splimp (); 1894154899Srik CE_LOCK (bd); 1895154899Srik /* hard_reset (c->board); */ 1896154899Srik CE_UNLOCK (bd); 1897154899Srik splx (s); 1898154899Srik return 0; 1899154899Srik#endif 1900154899Srik 1901154899Srik case SERIAL_GETCABLE: 1902154899Srik CE_DEBUG2 (d, ("ioctl: getcable\n")); 1903154899Srik if (c->type != T_E1) 1904154899Srik return EINVAL; 1905154899Srik s = splimp (); 1906154899Srik CE_LOCK (bd); 1907154899Srik *(int*)data = CABLE_TP; 1908154899Srik CE_UNLOCK (bd); 1909154899Srik splx (s); 1910154899Srik return 0; 1911154899Srik 1912154899Srik case SERIAL_GETDIR: 1913154899Srik CE_DEBUG2 (d, ("ioctl: getdir\n")); 1914154899Srik if (c->type != T_E1 && c->type != T_DATA) 1915154899Srik return EINVAL; 1916154899Srik *(int*)data = c->dir; 1917154899Srik return 0; 1918154899Srik 1919154899Srik case SERIAL_SETDIR: 1920154899Srik CE_DEBUG2 (d, ("ioctl: setdir\n")); 1921154899Srik /* Only for superuser! */ 1922154899Srik#if __FreeBSD_version < 500000 1923154899Srik error = suser (p); 1924180147Sdds#elif __FreeBSD_version < 700000 1925164033Srwatson error = suser (td); 1926154899Srik#else 1927164033Srwatson error = priv_check (td, PRIV_DRIVER); 1928154899Srik#endif 1929154899Srik if (error) 1930154899Srik return error; 1931154899Srik s = splimp (); 1932154899Srik CE_LOCK (bd); 1933154899Srik ce_set_dir (c, *(int*)data); 1934154899Srik CE_UNLOCK (bd); 1935154899Srik splx (s); 1936154899Srik return 0; 1937154899Srik 1938154899Srik case TIOCSDTR: /* Set DTR */ 1939154899Srik s = splimp (); 1940154899Srik CE_LOCK (bd); 1941154899Srik ce_set_dtr (c, 1); 1942154899Srik CE_UNLOCK (bd); 1943154899Srik splx (s); 1944154899Srik return 0; 1945154899Srik 1946154899Srik case TIOCCDTR: /* Clear DTR */ 1947154899Srik s = splimp (); 1948154899Srik CE_LOCK (bd); 1949154899Srik ce_set_dtr (c, 0); 1950154899Srik CE_UNLOCK (bd); 1951154899Srik splx (s); 1952154899Srik return 0; 1953154899Srik 1954154899Srik case TIOCMSET: /* Set DTR/RTS */ 1955154899Srik s = splimp (); 1956154899Srik CE_LOCK (bd); 1957154899Srik ce_set_dtr (c, (*(int*)data & TIOCM_DTR) ? 1 : 0); 1958154899Srik ce_set_rts (c, (*(int*)data & TIOCM_RTS) ? 1 : 0); 1959154899Srik CE_UNLOCK (bd); 1960154899Srik splx (s); 1961154899Srik return 0; 1962154899Srik 1963154899Srik case TIOCMBIS: /* Add DTR/RTS */ 1964154899Srik s = splimp (); 1965154899Srik CE_LOCK (bd); 1966154899Srik if (*(int*)data & TIOCM_DTR) ce_set_dtr (c, 1); 1967154899Srik if (*(int*)data & TIOCM_RTS) ce_set_rts (c, 1); 1968154899Srik CE_UNLOCK (bd); 1969154899Srik splx (s); 1970154899Srik return 0; 1971154899Srik 1972154899Srik case TIOCMBIC: /* Clear DTR/RTS */ 1973154899Srik s = splimp (); 1974154899Srik CE_LOCK (bd); 1975154899Srik if (*(int*)data & TIOCM_DTR) ce_set_dtr (c, 0); 1976154899Srik if (*(int*)data & TIOCM_RTS) ce_set_rts (c, 0); 1977154899Srik CE_UNLOCK (bd); 1978154899Srik splx (s); 1979154899Srik return 0; 1980154899Srik 1981154899Srik case TIOCMGET: /* Get modem status */ 1982154899Srik *(int*)data = ce_modem_status (c); 1983154899Srik return 0; 1984154899Srik } 1985154899Srik return ENOTTY; 1986154899Srik} 1987154899Srik 1988154899Srik#ifdef NETGRAPH 1989154899Srik#if __FreeBSD_version >= 500000 1990154899Srikstatic int ng_ce_constructor (node_p node) 1991154899Srik{ 1992154899Srik drv_t *d = NG_NODE_PRIVATE (node); 1993154899Srik#else 1994154899Srikstatic int ng_ce_constructor (node_p *node) 1995154899Srik{ 1996154899Srik drv_t *d = (*node)->private; 1997154899Srik#endif 1998154899Srik CE_DEBUG (d, ("Constructor\n")); 1999154899Srik return EINVAL; 2000154899Srik} 2001154899Srik 2002154899Srikstatic int ng_ce_newhook (node_p node, hook_p hook, const char *name) 2003154899Srik{ 2004154899Srik int s; 2005154899Srik#if __FreeBSD_version >= 500000 2006154899Srik drv_t *d = NG_NODE_PRIVATE (node); 2007154899Srik#else 2008154899Srik drv_t *d = node->private; 2009154899Srik#endif 2010154899Srik bdrv_t *bd = d->board->sys; 2011154899Srik 2012154899Srik CE_DEBUG (d, ("Newhook\n")); 2013154899Srik /* Attach debug hook */ 2014154899Srik if (strcmp (name, NG_CE_HOOK_DEBUG) == 0) { 2015154899Srik#if __FreeBSD_version >= 500000 2016154899Srik NG_HOOK_SET_PRIVATE (hook, NULL); 2017154899Srik#else 2018154899Srik hook->private = 0; 2019154899Srik#endif 2020154899Srik d->debug_hook = hook; 2021154899Srik return 0; 2022154899Srik } 2023154899Srik 2024154899Srik /* Check for raw hook */ 2025154899Srik if (strcmp (name, NG_CE_HOOK_RAW) != 0) 2026154899Srik return EINVAL; 2027154899Srik 2028154899Srik#if __FreeBSD_version >= 500000 2029154899Srik NG_HOOK_SET_PRIVATE (hook, d); 2030154899Srik#else 2031154899Srik hook->private = d; 2032154899Srik#endif 2033154899Srik d->hook = hook; 2034154899Srik s = splimp (); 2035154899Srik CE_LOCK (bd); 2036154899Srik ce_up (d); 2037154899Srik CE_UNLOCK (bd); 2038154899Srik splx (s); 2039154899Srik return 0; 2040154899Srik} 2041154899Srik 2042154899Srikstatic char *format_timeslots (u_long s) 2043154899Srik{ 2044154899Srik static char buf [100]; 2045154899Srik char *p = buf; 2046154899Srik int i; 2047154899Srik 2048154899Srik for (i=1; i<32; ++i) 2049154899Srik if ((s >> i) & 1) { 2050154899Srik int prev = (i > 1) & (s >> (i-1)); 2051154899Srik int next = (i < 31) & (s >> (i+1)); 2052154899Srik 2053154899Srik if (prev) { 2054154899Srik if (next) 2055154899Srik continue; 2056154899Srik *p++ = '-'; 2057154899Srik } else if (p > buf) 2058154899Srik *p++ = ','; 2059154899Srik 2060154899Srik if (i >= 10) 2061154899Srik *p++ = '0' + i / 10; 2062154899Srik *p++ = '0' + i % 10; 2063154899Srik } 2064154899Srik *p = 0; 2065154899Srik return buf; 2066154899Srik} 2067154899Srik 2068154899Srikstatic int print_modems (char *s, ce_chan_t *c, int need_header) 2069154899Srik{ 2070154899Srik int status = ce_modem_status (c); 2071154899Srik int length = 0; 2072154899Srik 2073154899Srik if (need_header) 2074154899Srik length += sprintf (s + length, " LE DTR DSR RTS CTS CD\n"); 2075154899Srik length += sprintf (s + length, "%4s %4s %4s %4s %4s %4s\n", 2076154899Srik status & TIOCM_LE ? "On" : "-", 2077154899Srik status & TIOCM_DTR ? "On" : "-", 2078154899Srik status & TIOCM_DSR ? "On" : "-", 2079154899Srik status & TIOCM_RTS ? "On" : "-", 2080154899Srik status & TIOCM_CTS ? "On" : "-", 2081154899Srik status & TIOCM_CD ? "On" : "-"); 2082154899Srik return length; 2083154899Srik} 2084154899Srik 2085154899Srikstatic int print_stats (char *s, ce_chan_t *c, int need_header) 2086154899Srik{ 2087154899Srik int length = 0; 2088154899Srik 2089154899Srik if (need_header) 2090154899Srik length += sprintf (s + length, " Rintr Tintr Mintr Ibytes Ipkts Ierrs Obytes Opkts Oerrs\n"); 2091154899Srik length += sprintf (s + length, "%7ld %7ld %7ld %8lu %7ld %7ld %8lu %7ld %7ld\n", 2092154899Srik c->rintr, c->tintr, 0l, (unsigned long) c->ibytes, 2093154899Srik c->ipkts, c->overrun + c->frame + c->crc, 2094154899Srik (unsigned long) c->obytes, c->opkts, c->underrun); 2095154899Srik return length; 2096154899Srik} 2097154899Srik 2098154899Srikstatic char *format_e1_status (u_char status) 2099154899Srik{ 2100154899Srik static char buf [80]; 2101154899Srik 2102154899Srik if (status & E1_NOALARM) 2103154899Srik return "Ok"; 2104154899Srik buf[0] = 0; 2105154899Srik if (status & E1_LOS) strcat (buf, ",LOS"); 2106154899Srik if (status & E1_AIS) strcat (buf, ",AIS"); 2107154899Srik if (status & E1_LOF) strcat (buf, ",LOF"); 2108154899Srik if (status & E1_LOMF) strcat (buf, ",LOMF"); 2109154899Srik if (status & E1_FARLOF) strcat (buf, ",FARLOF"); 2110154899Srik if (status & E1_AIS16) strcat (buf, ",AIS16"); 2111154899Srik if (status & E1_FARLOMF) strcat (buf, ",FARLOMF"); 2112154899Srik if (status & E1_TSTREQ) strcat (buf, ",TSTREQ"); 2113154899Srik if (status & E1_TSTERR) strcat (buf, ",TSTERR"); 2114154899Srik if (buf[0] == ',') 2115154899Srik return buf+1; 2116154899Srik return "Unknown"; 2117154899Srik} 2118154899Srik 2119154899Srikstatic int print_frac (char *s, int leftalign, u_long numerator, u_long divider) 2120154899Srik{ 2121154899Srik int n, length = 0; 2122154899Srik 2123154899Srik if (numerator < 1 || divider < 1) { 2124154899Srik length += sprintf (s+length, leftalign ? "/- " : " -"); 2125154899Srik return length; 2126154899Srik } 2127154899Srik n = (int) (0.5 + 1000.0 * numerator / divider); 2128154899Srik if (n < 1000) { 2129154899Srik length += sprintf (s+length, leftalign ? "/.%-3d" : " .%03d", n); 2130154899Srik return length; 2131154899Srik } 2132154899Srik *(s + length) = leftalign ? '/' : ' '; 2133154899Srik length ++; 2134154899Srik 2135154899Srik if (n >= 1000000) n = (n+500) / 1000 * 1000; 2136154899Srik else if (n >= 100000) n = (n+50) / 100 * 100; 2137154899Srik else if (n >= 10000) n = (n+5) / 10 * 10; 2138154899Srik 2139154899Srik switch (n) { 2140154899Srik case 1000: length += printf (s+length, ".999"); return length; 2141154899Srik case 10000: n = 9990; break; 2142154899Srik case 100000: n = 99900; break; 2143154899Srik case 1000000: n = 999000; break; 2144154899Srik } 2145154899Srik if (n < 10000) length += sprintf (s+length, "%d.%d", n/1000, n/10%100); 2146154899Srik else if (n < 100000) length += sprintf (s+length, "%d.%d", n/1000, n/100%10); 2147154899Srik else if (n < 1000000) length += sprintf (s+length, "%d.", n/1000); 2148154899Srik else length += sprintf (s+length, "%d", n/1000); 2149154899Srik 2150154899Srik return length; 2151154899Srik} 2152154899Srik 2153154899Srikstatic int print_e1_stats (char *s, ce_chan_t *c) 2154154899Srik{ 2155154899Srik struct e1_counters total; 2156154899Srik u_long totsec; 2157154899Srik int length = 0; 2158154899Srik 2159154899Srik totsec = c->totsec + c->cursec; 2160154899Srik total.bpv = c->total.bpv + c->currnt.bpv; 2161154899Srik total.fse = c->total.fse + c->currnt.fse; 2162154899Srik total.crce = c->total.crce + c->currnt.crce; 2163154899Srik total.rcrce = c->total.rcrce + c->currnt.rcrce; 2164154899Srik total.uas = c->total.uas + c->currnt.uas; 2165154899Srik total.les = c->total.les + c->currnt.les; 2166154899Srik total.es = c->total.es + c->currnt.es; 2167154899Srik total.bes = c->total.bes + c->currnt.bes; 2168154899Srik total.ses = c->total.ses + c->currnt.ses; 2169154899Srik total.oofs = c->total.oofs + c->currnt.oofs; 2170154899Srik total.css = c->total.css + c->currnt.css; 2171154899Srik total.dm = c->total.dm + c->currnt.dm; 2172154899Srik 2173154899Srik length += sprintf (s + length, " Unav/Degr Bpv/Fsyn CRC/RCRC Err/Lerr Sev/Bur Oof/Slp Status\n"); 2174154899Srik 2175154899Srik /* Unavailable seconds, degraded minutes */ 2176154899Srik length += print_frac (s + length, 0, c->currnt.uas, c->cursec); 2177154899Srik length += print_frac (s + length, 1, 60 * c->currnt.dm, c->cursec); 2178154899Srik 2179154899Srik /* Bipolar violations, frame sync errors */ 2180154899Srik length += print_frac (s + length, 0, c->currnt.bpv, c->cursec); 2181154899Srik length += print_frac (s + length, 1, c->currnt.fse, c->cursec); 2182154899Srik 2183154899Srik /* CRC errors, remote CRC errors (E-bit) */ 2184154899Srik length += print_frac (s + length, 0, c->currnt.crce, c->cursec); 2185154899Srik length += print_frac (s + length, 1, c->currnt.rcrce, c->cursec); 2186154899Srik 2187154899Srik /* Errored seconds, line errored seconds */ 2188154899Srik length += print_frac (s + length, 0, c->currnt.es, c->cursec); 2189154899Srik length += print_frac (s + length, 1, c->currnt.les, c->cursec); 2190154899Srik 2191154899Srik /* Severely errored seconds, burst errored seconds */ 2192154899Srik length += print_frac (s + length, 0, c->currnt.ses, c->cursec); 2193154899Srik length += print_frac (s + length, 1, c->currnt.bes, c->cursec); 2194154899Srik 2195154899Srik /* Out of frame seconds, controlled slip seconds */ 2196154899Srik length += print_frac (s + length, 0, c->currnt.oofs, c->cursec); 2197154899Srik length += print_frac (s + length, 1, c->currnt.css, c->cursec); 2198154899Srik 2199154899Srik length += sprintf (s + length, " %s\n", format_e1_status (c->status)); 2200154899Srik 2201154899Srik /* Print total statistics. */ 2202154899Srik length += print_frac (s + length, 0, total.uas, totsec); 2203154899Srik length += print_frac (s + length, 1, 60 * total.dm, totsec); 2204154899Srik 2205154899Srik length += print_frac (s + length, 0, total.bpv, totsec); 2206154899Srik length += print_frac (s + length, 1, total.fse, totsec); 2207154899Srik 2208154899Srik length += print_frac (s + length, 0, total.crce, totsec); 2209154899Srik length += print_frac (s + length, 1, total.rcrce, totsec); 2210154899Srik 2211154899Srik length += print_frac (s + length, 0, total.es, totsec); 2212154899Srik length += print_frac (s + length, 1, total.les, totsec); 2213154899Srik 2214154899Srik length += print_frac (s + length, 0, total.ses, totsec); 2215154899Srik length += print_frac (s + length, 1, total.bes, totsec); 2216154899Srik 2217154899Srik length += print_frac (s + length, 0, total.oofs, totsec); 2218154899Srik length += print_frac (s + length, 1, total.css, totsec); 2219154899Srik 2220154899Srik length += sprintf (s + length, " -- Total\n"); 2221154899Srik return length; 2222154899Srik} 2223154899Srik 2224154899Srikstatic int print_chan (char *s, ce_chan_t *c) 2225154899Srik{ 2226154899Srik drv_t *d = c->sys; 2227154899Srik int length = 0; 2228154899Srik 2229154899Srik length += sprintf (s + length, "ce%d", c->board->num * NCHAN + c->num); 2230154899Srik if (d->chan->debug) 2231154899Srik length += sprintf (s + length, " debug=%d", d->chan->debug); 2232154899Srik 2233154899Srik if (c->board->mux) { 2234154899Srik length += sprintf (s + length, " cfg=C"); 2235154899Srik } else { 2236154899Srik length += sprintf (s + length, " cfg=A"); 2237154899Srik } 2238154899Srik 2239154899Srik if (c->baud) 2240154899Srik length += sprintf (s + length, " %ld", c->baud); 2241154899Srik else 2242154899Srik length += sprintf (s + length, " extclock"); 2243154899Srik 2244154899Srik if (c->type == T_E1) 2245154899Srik switch (c->gsyn) { 2246154899Srik case GSYN_INT : length += sprintf (s + length, " syn=int"); break; 2247154899Srik case GSYN_RCV : length += sprintf (s + length, " syn=rcv"); break; 2248154899Srik case GSYN_RCV0 : length += sprintf (s + length, " syn=rcv0"); break; 2249154899Srik case GSYN_RCV1 : length += sprintf (s + length, " syn=rcv1"); break; 2250154899Srik } 2251154899Srik if (c->type == T_E1) 2252154899Srik length += sprintf (s + length, " higain=%s", c->higain ? "on" : "off"); 2253154899Srik 2254154899Srik length += sprintf (s + length, " loop=%s", c->lloop ? "on" : "off"); 2255154899Srik 2256154899Srik if (c->type == T_E1) 2257154899Srik length += sprintf (s + length, " ts=%s", format_timeslots (c->ts)); 2258154899Srik length += sprintf (s + length, "\n"); 2259154899Srik return length; 2260154899Srik} 2261154899Srik 2262154899Srik#if __FreeBSD_version >= 500000 2263154899Srikstatic int ng_ce_rcvmsg (node_p node, item_p item, hook_p lasthook) 2264154899Srik{ 2265154899Srik drv_t *d = NG_NODE_PRIVATE (node); 2266154899Srik struct ng_mesg *msg; 2267154899Srik#else 2268154899Srikstatic int ng_ce_rcvmsg (node_p node, struct ng_mesg *msg, 2269154899Srik const char *retaddr, struct ng_mesg **rptr) 2270154899Srik{ 2271154899Srik drv_t *d = node->private; 2272154899Srik#endif 2273154899Srik struct ng_mesg *resp = NULL; 2274154899Srik int error = 0; 2275154899Srik 2276154899Srik CE_DEBUG (d, ("Rcvmsg\n")); 2277154899Srik#if __FreeBSD_version >= 500000 2278154899Srik NGI_GET_MSG (item, msg); 2279154899Srik#endif 2280154899Srik switch (msg->header.typecookie) { 2281154899Srik default: 2282154899Srik error = EINVAL; 2283154899Srik break; 2284154899Srik 2285154899Srik case NGM_CE_COOKIE: 2286154899Srik printf ("Not implemented yet\n"); 2287154899Srik error = EINVAL; 2288154899Srik break; 2289154899Srik 2290154899Srik case NGM_GENERIC_COOKIE: 2291154899Srik switch (msg->header.cmd) { 2292154899Srik default: 2293154899Srik error = EINVAL; 2294154899Srik break; 2295154899Srik 2296154899Srik case NGM_TEXT_STATUS: { 2297154899Srik char *s; 2298154899Srik int l = 0; 2299154899Srik int dl = sizeof (struct ng_mesg) + 730; 2300154899Srik 2301154899Srik#if __FreeBSD_version >= 500000 2302154899Srik NG_MKRESPONSE (resp, msg, dl, M_NOWAIT); 2303154899Srik if (! resp) { 2304154899Srik error = ENOMEM; 2305154899Srik break; 2306154899Srik } 2307154899Srik#else 2308184205Sdes resp = malloc (M_NETGRAPH, M_NOWAIT); 2309154899Srik if (! resp) { 2310154899Srik error = ENOMEM; 2311154899Srik break; 2312154899Srik } 2313154899Srik bzero (resp, dl); 2314154899Srik#endif 2315154899Srik s = (resp)->data; 2316154899Srik if (d) { 2317154899Srik l += print_chan (s + l, d->chan); 2318154899Srik l += print_stats (s + l, d->chan, 1); 2319154899Srik l += print_modems (s + l, d->chan, 1); 2320154899Srik l += print_e1_stats (s + l, d->chan); 2321154899Srik } else 2322154899Srik l += sprintf (s + l, "Error: node not connect to channel"); 2323154899Srik#if __FreeBSD_version < 500000 2324154899Srik (resp)->header.version = NG_VERSION; 2325154899Srik (resp)->header.arglen = strlen (s) + 1; 2326154899Srik (resp)->header.token = msg->header.token; 2327154899Srik (resp)->header.typecookie = NGM_CE_COOKIE; 2328154899Srik (resp)->header.cmd = msg->header.cmd; 2329154899Srik#endif 2330193813Simp strncpy ((resp)->header.cmdstr, "status", NG_CMDSTRSIZ); 2331154899Srik } 2332154899Srik break; 2333154899Srik } 2334154899Srik break; 2335154899Srik } 2336154899Srik#if __FreeBSD_version >= 500000 2337154899Srik NG_RESPOND_MSG (error, node, item, resp); 2338154899Srik NG_FREE_MSG (msg); 2339154899Srik#else 2340154899Srik *rptr = resp; 2341184205Sdes free (msg, M_NETGRAPH); 2342154899Srik#endif 2343154899Srik return error; 2344154899Srik} 2345154899Srik 2346154899Srik#if __FreeBSD_version >= 500000 2347154899Srikstatic int ng_ce_rcvdata (hook_p hook, item_p item) 2348154899Srik{ 2349154899Srik drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE(hook)); 2350154899Srik struct mbuf *m; 2351154899Srik#if __FreeBSD_version < 502120 2352154899Srik meta_p meta; 2353154899Srik#else 2354154899Srik struct ng_tag_prio *ptag; 2355154899Srik#endif 2356154899Srik#else 2357154899Srikstatic int ng_ce_rcvdata (hook_p hook, struct mbuf *m, meta_p meta) 2358154899Srik{ 2359154899Srik drv_t *d = hook->node->private; 2360154899Srik#endif 2361154899Srik bdrv_t *bd = d->board->sys; 2362154899Srik struct ifqueue *q; 2363154899Srik int s; 2364154899Srik 2365154899Srik CE_DEBUG2 (d, ("Rcvdata\n")); 2366154899Srik#if __FreeBSD_version >= 500000 2367154899Srik NGI_GET_M (item, m); 2368154899Srik#if __FreeBSD_version < 502120 2369154899Srik NGI_GET_META (item, meta); 2370154899Srik#endif 2371154899Srik NG_FREE_ITEM (item); 2372154899Srik if (! NG_HOOK_PRIVATE (hook) || ! d) { 2373154899Srik NG_FREE_M (m); 2374154899Srik#if __FreeBSD_version < 502120 2375154899Srik NG_FREE_META (meta); 2376154899Srik#endif 2377154899Srik#else 2378154899Srik if (! hook->private || ! d) { 2379154899Srik NG_FREE_DATA (m,meta); 2380154899Srik#endif 2381154899Srik return ENETDOWN; 2382154899Srik } 2383154899Srik 2384154899Srik#if __FreeBSD_version >= 502120 2385154899Srik /* Check for high priority data */ 2386154899Srik if ((ptag = (struct ng_tag_prio *)m_tag_locate(m, NGM_GENERIC_COOKIE, 2387154899Srik NG_TAG_PRIO, NULL)) != NULL && (ptag->priority > NG_PRIO_CUTOFF) ) 2388154899Srik q = &d->hi_queue; 2389154899Srik else 2390154899Srik q = &d->queue; 2391154899Srik#else 2392154899Srik q = (meta && meta->priority > 0) ? &d->hi_queue : &d->queue; 2393154899Srik#endif 2394154899Srik 2395154899Srik s = splimp (); 2396154899Srik CE_LOCK (bd); 2397154899Srik#if __FreeBSD_version >= 500000 2398154899Srik IF_LOCK (q); 2399154899Srik if (_IF_QFULL (q)) { 2400154899Srik IF_UNLOCK (q); 2401154899Srik CE_UNLOCK (bd); 2402154899Srik splx (s); 2403154899Srik NG_FREE_M (m); 2404154899Srik#if __FreeBSD_version < 502120 2405154899Srik NG_FREE_META (meta); 2406154899Srik#endif 2407154899Srik return ENOBUFS; 2408154899Srik } 2409154899Srik _IF_ENQUEUE (q, m); 2410154899Srik IF_UNLOCK (q); 2411154899Srik#else 2412154899Srik if (IF_QFULL (q)) { 2413154899Srik IF_DROP (q); 2414154899Srik CE_UNLOCK (bd); 2415154899Srik splx (s); 2416154899Srik NG_FREE_DATA (m, meta); 2417154899Srik return ENOBUFS; 2418154899Srik } 2419154899Srik IF_ENQUEUE (q, m); 2420154899Srik#endif 2421154899Srik ce_start (d); 2422154899Srik CE_UNLOCK (bd); 2423154899Srik splx (s); 2424154899Srik return 0; 2425154899Srik} 2426154899Srik 2427154899Srikstatic int ng_ce_rmnode (node_p node) 2428154899Srik{ 2429154899Srik#if __FreeBSD_version >= 500000 2430154899Srik drv_t *d = NG_NODE_PRIVATE (node); 2431154899Srik 2432154899Srik CE_DEBUG (d, ("Rmnode\n")); 2433154899Srik if (d && d->running) { 2434154899Srik bdrv_t *bd = d->board->sys; 2435154899Srik int s = splimp (); 2436154899Srik CE_LOCK (bd); 2437154899Srik ce_down (d); 2438154899Srik CE_UNLOCK (bd); 2439154899Srik splx (s); 2440154899Srik } 2441154899Srik#ifdef KLD_MODULE 2442154899Srik#if __FreeBSD_version >= 502120 2443154899Srik if (node->nd_flags & NGF_REALLY_DIE) { 2444154899Srik#else 2445154899Srik if (node->nd_flags & NG_REALLY_DIE) { 2446154899Srik#endif 2447154899Srik NG_NODE_SET_PRIVATE (node, NULL); 2448154899Srik NG_NODE_UNREF (node); 2449154899Srik } 2450154899Srik#if __FreeBSD_version >= 502120 2451298955Spfg NG_NODE_REVIVE(node); /* Persistent node */ 2452154899Srik#else 2453154899Srik node->nd_flags &= ~NG_INVALID; 2454154899Srik#endif 2455154899Srik#endif 2456154899Srik#else /* __FreeBSD_version < 500000 */ 2457154899Srik drv_t *d = node->private; 2458154899Srik 2459154899Srik if (d && d->running) { 2460154899Srik bdrv_t *bd = d->board->sys; 2461154899Srik int s = splimp (); 2462154899Srik CE_LOCK (bd); 2463154899Srik ce_down (d); 2464154899Srik CE_UNLOCK (bd); 2465154899Srik splx (s); 2466154899Srik } 2467154899Srik 2468154899Srik node->flags |= NG_INVALID; 2469154899Srik ng_cutlinks (node); 2470154899Srik#ifdef KLD_MODULE 2471154899Srik ng_unname (node); 2472154899Srik ng_unref (node); 2473154899Srik#endif 2474154899Srik#endif 2475154899Srik return 0; 2476154899Srik} 2477154899Srik 2478154899Srikstatic int ng_ce_connect (hook_p hook) 2479154899Srik{ 2480154899Srik#if __FreeBSD_version >= 500000 2481154899Srik drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); 2482154899Srik#else 2483154899Srik drv_t *d = hook->node->private; 2484154899Srik#endif 2485154899Srik 2486154899Srik if (d) { 2487154899Srik CE_DEBUG (d, ("Connect\n")); 2488199407Sjhb callout_reset (&d->timeout_handle, hz, ce_watchdog_timer, d); 2489154899Srik } 2490154899Srik 2491154899Srik return 0; 2492154899Srik} 2493154899Srik 2494154899Srikstatic int ng_ce_disconnect (hook_p hook) 2495154899Srik{ 2496154899Srik#if __FreeBSD_version >= 500000 2497154899Srik drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); 2498154899Srik#else 2499154899Srik drv_t *d = hook->node->private; 2500154899Srik#endif 2501154899Srik 2502154899Srik if (d) { 2503154899Srik CE_DEBUG (d, ("Disconnect\n")); 2504154899Srik#if __FreeBSD_version >= 500000 2505154899Srik if (NG_HOOK_PRIVATE (hook)) 2506154899Srik#else 2507154899Srik if (hook->private) 2508154899Srik#endif 2509154899Srik { 2510154899Srik bdrv_t *bd = d->board->sys; 2511154899Srik int s = splimp (); 2512154899Srik CE_LOCK (bd); 2513154899Srik ce_down (d); 2514154899Srik CE_UNLOCK (bd); 2515154899Srik splx (s); 2516154899Srik } 2517154899Srik /* If we were wait it than it reasserted now, just stop it. */ 2518154899Srik if (!callout_drain (&d->timeout_handle)) 2519154899Srik callout_stop (&d->timeout_handle); 2520154899Srik } 2521154899Srik return 0; 2522154899Srik} 2523154899Srik#endif 2524154899Srik 2525154899Srikstatic int ce_modevent (module_t mod, int type, void *unused) 2526154899Srik{ 2527154899Srik#if __FreeBSD_version < 500000 2528154899Srik dev_t dev; 2529154899Srik struct cdevsw *cdsw; 2530154899Srik#endif 2531154899Srik static int load_count = 0; 2532154899Srik 2533154899Srik#if __FreeBSD_version < 500000 2534154899Srik dev = makedev (CDEV_MAJOR, 0); 2535154899Srik#endif 2536154899Srik 2537154899Srik switch (type) { 2538154899Srik case MOD_LOAD: 2539154899Srik#if __FreeBSD_version < 500000 2540154899Srik if (dev != NODEV && 2541154899Srik (cdsw = devsw (dev)) && 2542154899Srik cdsw->d_maj == CDEV_MAJOR) { 2543154899Srik printf ("Tau32-PCI driver is already in system\n"); 2544154899Srik return (ENXIO); 2545154899Srik } 2546154899Srik#endif 2547154899Srik#if __FreeBSD_version >= 500000 && defined NETGRAPH 2548154899Srik if (ng_newtype (&typestruct)) 2549154899Srik printf ("Failed to register ng_ce\n"); 2550154899Srik#endif 2551154899Srik ++load_count; 2552154899Srik#if __FreeBSD_version <= 500000 2553154899Srik cdevsw_add (&ce_cdevsw); 2554154899Srik#endif 2555154899Srik#if __FreeBSD_version >= 500000 2556283291Sjkim callout_init (&timeout_handle, 1); 2557154899Srik#else 2558154899Srik callout_init (&timeout_handle); 2559154899Srik#endif 2560154899Srik callout_reset (&timeout_handle, hz*5, ce_timeout, 0); 2561154899Srik break; 2562154899Srik case MOD_UNLOAD: 2563154899Srik if (load_count == 1) { 2564154899Srik printf ("Removing device entry for Tau32-PCI\n"); 2565154899Srik#if __FreeBSD_version <= 500000 2566154899Srik cdevsw_remove (&ce_cdevsw); 2567154899Srik#endif 2568154899Srik#if __FreeBSD_version >= 500000 && defined NETGRAPH 2569154899Srik ng_rmtype (&typestruct); 2570154899Srik#endif 2571154899Srik } 2572154899Srik /* If we were wait it than it reasserted now, just stop it. 2573154899Srik * Actually we shouldn't get this condition. But code could be 2574154899Srik * changed in the future, so just be a litle paranoid. 2575154899Srik */ 2576154899Srik if (!callout_drain (&timeout_handle)) 2577154899Srik callout_stop (&timeout_handle); 2578154899Srik --load_count; 2579154899Srik break; 2580154899Srik case MOD_SHUTDOWN: 2581154899Srik break; 2582154899Srik } 2583154899Srik return 0; 2584154899Srik} 2585154899Srik 2586154899Srik#ifdef NETGRAPH 2587154899Srik#if __FreeBSD_version >= 502100 2588154899Srikstatic struct ng_type typestruct = { 2589154899Srik .version = NG_ABI_VERSION, 2590154899Srik .name = NG_CE_NODE_TYPE, 2591154899Srik .constructor = ng_ce_constructor, 2592154899Srik .rcvmsg = ng_ce_rcvmsg, 2593154899Srik .shutdown = ng_ce_rmnode, 2594154899Srik .newhook = ng_ce_newhook, 2595154899Srik .connect = ng_ce_connect, 2596154899Srik .rcvdata = ng_ce_rcvdata, 2597154899Srik .disconnect = ng_ce_disconnect, 2598154899Srik}; 2599154899Srik#else /* __FreeBSD_version < 502100 */ 2600154899Srikstatic struct ng_type typestruct = { 2601154899Srik#if __FreeBSD_version >= 500000 2602154899Srik NG_ABI_VERSION, 2603154899Srik#else 2604154899Srik NG_VERSION, 2605154899Srik#endif 2606154899Srik NG_CE_NODE_TYPE, 2607154899Srik ce_modevent, 2608154899Srik ng_ce_constructor, 2609154899Srik ng_ce_rcvmsg, 2610154899Srik ng_ce_rmnode, 2611154899Srik ng_ce_newhook, 2612154899Srik NULL, 2613154899Srik ng_ce_connect, 2614154899Srik ng_ce_rcvdata, 2615154899Srik#if __FreeBSD_version < 500000 2616154899Srik NULL, 2617154899Srik#endif 2618154899Srik ng_ce_disconnect, 2619154899Srik NULL 2620154899Srik}; 2621154899Srik#endif /* __FreeBSD_version < 502100 */ 2622154899Srik 2623154899Srik#endif /*NETGRAPH*/ 2624154899Srik 2625154899Srik#if __FreeBSD_version >= 500000 2626154899Srik#ifdef NETGRAPH 2627154899SrikMODULE_DEPEND (ng_ce, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); 2628154899Srik#else 2629154899SrikMODULE_DEPEND (ce, sppp, 1, 1, 1); 2630154899Srik#endif 2631154899Srik#ifdef KLD_MODULE 2632154899SrikDRIVER_MODULE (cemod, pci, ce_driver, ce_devclass, ce_modevent, NULL); 2633154899Srik#else 2634154899SrikDRIVER_MODULE (ce, pci, ce_driver, ce_devclass, ce_modevent, NULL); 2635154899Srik#endif 2636154899Srik#else /* if __FreeBSD_version < 500000*/ 2637154899Srik#ifdef NETGRAPH 2638154899SrikDRIVER_MODULE (ce, pci, ce_driver, ce_devclass, ng_mod_event, &typestruct); 2639154899Srik#else 2640154899SrikDRIVER_MODULE (ce, pci, ce_driver, ce_devclass, ce_modevent, NULL); 2641154899Srik#endif 2642154899Srik#endif /* __FreeBSD_version < 500000 */ 2643154899Srik#endif /* NPCI */ 2644