1142384Sharti/*- 2142384Sharti * Copyright (c) 2003 3142384Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4142384Sharti * All rights reserved. 5142384Sharti * 6142384Sharti * Author: Hartmut Brandt <harti@freebsd.org> 7142384Sharti * 8142384Sharti * Redistribution and use in source and binary forms, with or without 9142384Sharti * modification, are permitted provided that the following conditions 10142384Sharti * are met: 11142384Sharti * 1. Redistributions of source code must retain the above copyright 12142384Sharti * notice, this list of conditions and the following disclaimer. 13142384Sharti * 2. Redistributions in binary form must reproduce the above copyright 14142384Sharti * notice, this list of conditions and the following disclaimer in the 15142384Sharti * documentation and/or other materials provided with the distribution. 16142384Sharti * 17142384Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18142384Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19142384Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20142384Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21142384Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22142384Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23142384Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24142384Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25142384Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26142384Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27142384Sharti * SUCH DAMAGE. 28142384Sharti */ 29142384Sharti 30142384Sharti#include <sys/cdefs.h> 31142384Sharti__FBSDID("$FreeBSD: releng/11.0/sys/dev/utopia/suni.c 142384 2005-02-24 16:56:36Z harti $"); 32142384Sharti 33142384Sharti#include <sys/param.h> 34142384Sharti#include <sys/systm.h> 35142384Sharti#include <sys/unistd.h> 36142384Sharti#include <sys/kernel.h> 37142384Sharti#include <sys/kthread.h> 38142384Sharti#include <sys/proc.h> 39142384Sharti#include <sys/bus.h> 40142384Sharti#include <sys/malloc.h> 41142384Sharti#include <sys/module.h> 42142384Sharti#include <sys/sysctl.h> 43142384Sharti#include <sys/lock.h> 44142384Sharti#include <sys/mutex.h> 45142384Sharti#include <sys/socket.h> 46142384Sharti 47142384Sharti#include <net/if.h> 48142384Sharti#include <net/if_var.h> 49142384Sharti#include <net/if_media.h> 50142384Sharti#include <net/if_atm.h> 51142384Sharti 52142384Sharti#include <dev/utopia/suni.h> 53142384Sharti#include <dev/utopia/utopia.h> 54142384Sharti#include <dev/utopia/utopia_priv.h> 55142384Sharti 56142384Sharti/* 57142384Sharti * set SONET/SDH mode 58142384Sharti */ 59142384Shartistatic int 60142384Shartisuni_set_sdh(struct utopia *utp, int sdh) 61142384Sharti{ 62142384Sharti int err; 63142384Sharti 64142384Sharti if (sdh) 65142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1, 66142384Sharti SUNI_REGM_TPOPAPTR_S, 67142384Sharti SUNI_REGM_SDH << SUNI_REGS_TPOPAPTR_S); 68142384Sharti else 69142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1, 70142384Sharti SUNI_REGM_TPOPAPTR_S, 71142384Sharti SUNI_REGM_SONET << SUNI_REGS_TPOPAPTR_S); 72142384Sharti if (err != 0) 73142384Sharti return (err); 74142384Sharti 75142384Sharti utp->state &= ~UTP_ST_SDH; 76142384Sharti if (sdh) 77142384Sharti utp->state |= UTP_ST_SDH; 78142384Sharti 79142384Sharti return (0); 80142384Sharti} 81142384Sharti 82142384Sharti/* 83142384Sharti * set idle/unassigned cells 84142384Sharti */ 85142384Shartistatic int 86142384Shartisuni_set_unass(struct utopia *utp, int unass) 87142384Sharti{ 88142384Sharti int err; 89142384Sharti 90142384Sharti if (unass) 91142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_TACPIDLEH, 92142384Sharti 0xff, (0 << SUNI_REGS_TACPIDLEH_CLP)); 93142384Sharti else 94142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_TACPIDLEH, 95142384Sharti 0xff, (1 << SUNI_REGS_TACPIDLEH_CLP)); 96142384Sharti if (err != 0) 97142384Sharti return (err); 98142384Sharti 99142384Sharti utp->state &= ~UTP_ST_UNASS; 100142384Sharti if (unass) 101142384Sharti utp->state |= UTP_ST_UNASS; 102142384Sharti 103142384Sharti return (0); 104142384Sharti} 105142384Sharti 106142384Sharti/* 107142384Sharti * enable/disable scrambling 108142384Sharti */ 109142384Shartistatic int 110142384Shartisuni_set_noscramb(struct utopia *utp, int noscramb) 111142384Sharti{ 112142384Sharti int err; 113142384Sharti 114142384Sharti if (noscramb) { 115142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_TACPCTRL, 116142384Sharti SUNI_REGM_TACPCTRL_DSCR, SUNI_REGM_TACPCTRL_DSCR); 117142384Sharti if (err) 118142384Sharti return (err); 119142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_RACPCTRL, 120142384Sharti SUNI_REGM_RACPCTRL_DDSCR, SUNI_REGM_RACPCTRL_DDSCR); 121142384Sharti if (err) 122142384Sharti return (err); 123142384Sharti utp->state |= UTP_ST_NOSCRAMB; 124142384Sharti } else { 125142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_TACPCTRL, 126142384Sharti SUNI_REGM_TACPCTRL_DSCR, 0); 127142384Sharti if (err) 128142384Sharti return (err); 129142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_RACPCTRL, 130142384Sharti SUNI_REGM_RACPCTRL_DDSCR, 0); 131142384Sharti if (err) 132142384Sharti return (err); 133142384Sharti utp->state &= ~UTP_ST_NOSCRAMB; 134142384Sharti } 135142384Sharti return (0); 136142384Sharti} 137142384Sharti 138142384Sharti/* 139142384Sharti * Get current carrier state 140142384Sharti */ 141142384Shartistatic int 142142384Shartisuni_update_carrier(struct utopia *utp) 143142384Sharti{ 144142384Sharti int err; 145142384Sharti uint8_t reg; 146142384Sharti u_int n = 1; 147142384Sharti 148142384Sharti if ((err = UTP_READREGS(utp, SUNI_REGO_RSOPSIS, ®, &n)) != 0) { 149142384Sharti utp->carrier = UTP_CARR_UNKNOWN; 150142384Sharti return (err); 151142384Sharti } 152142384Sharti utopia_check_carrier(utp, !(reg & SUNI_REGM_RSOPSIS_LOSV)); 153142384Sharti return (0); 154142384Sharti} 155142384Sharti 156142384Sharti/* 157142384Sharti * Set the SUNI chip to reflect the current state in utopia. 158142384Sharti * Assume, that the chip has been reset. 159142384Sharti */ 160142384Shartistatic int 161142384Shartisuni_set_chip(struct utopia *utp) 162142384Sharti{ 163142384Sharti int err = 0; 164142384Sharti 165142384Sharti /* set sonet/sdh */ 166142384Sharti err |= utopia_set_sdh(utp, utp->state & UTP_ST_SDH); 167142384Sharti 168142384Sharti /* unassigned or idle cells */ 169142384Sharti err |= utopia_set_unass(utp, utp->state & UTP_ST_UNASS); 170142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_TACPIDLEP, 0xff, 0x6a); 171142384Sharti 172142384Sharti /* set scrambling */ 173142384Sharti err |= utopia_set_noscramb(utp, utp->state & UTP_ST_NOSCRAMB); 174142384Sharti 175142384Sharti /* loopback */ 176142384Sharti err |= utopia_set_loopback(utp, utp->loopback); 177142384Sharti 178142384Sharti /* update carrier state */ 179142384Sharti err |= utopia_update_carrier(utp); 180142384Sharti 181142384Sharti /* enable interrupts on LOS */ 182142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RSOPCIE, 183142384Sharti SUNI_REGM_RSOPCIE_LOSE, SUNI_REGM_RSOPCIE_LOSE); 184142384Sharti 185142384Sharti return (err ? EIO : 0); 186142384Sharti} 187142384Sharti 188142384Sharti/* 189142384Sharti * Reset the SUNI chip to reflect the current state of utopia. 190142384Sharti */ 191142384Shartistatic int 192142384Shartisuni_reset_default(struct utopia *utp) 193142384Sharti{ 194142384Sharti int err = 0; 195142384Sharti 196142384Sharti if (!(utp->flags & UTP_FL_NORESET)) { 197142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, 198142384Sharti SUNI_REGM_MRESET_RESET, SUNI_REGM_MRESET_RESET); 199142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, 200142384Sharti SUNI_REGM_MRESET_RESET, 0); 201142384Sharti } 202142384Sharti 203142384Sharti /* disable test mode */ 204142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_MTEST, 0xff, 0x00); 205142384Sharti 206142384Sharti err |= suni_set_chip(utp); 207142384Sharti 208142384Sharti return (err ? EIO : 0); 209142384Sharti} 210142384Sharti 211142384Sharti/* 212142384Sharti * Set loopback mode for the Lite 213142384Sharti */ 214142384Shartistatic int 215142384Shartisuni_set_loopback_lite(struct utopia *utp, u_int mode) 216142384Sharti{ 217142384Sharti int err; 218142384Sharti uint32_t val; 219142384Sharti u_int nmode; 220142384Sharti 221142384Sharti val = 0; 222142384Sharti nmode = mode; 223142384Sharti if (mode & UTP_LOOP_TIME) { 224142384Sharti nmode &= ~UTP_LOOP_TIME; 225142384Sharti val |= SUNI_REGM_MCTRL_LOOPT; 226142384Sharti } 227142384Sharti if (mode & UTP_LOOP_DIAG) { 228142384Sharti nmode &= ~UTP_LOOP_DIAG; 229142384Sharti val |= SUNI_REGM_MCTRL_DLE; 230142384Sharti } 231142384Sharti if (mode & UTP_LOOP_LINE) { 232142384Sharti nmode &= ~UTP_LOOP_LINE; 233142384Sharti if (val & SUNI_REGM_MCTRL_DLE) 234142384Sharti return (EINVAL); 235142384Sharti val |= SUNI_REGM_MCTRL_LLE; 236142384Sharti } 237142384Sharti if (nmode != 0) 238142384Sharti return (EINVAL); 239142384Sharti 240142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_MCTRL, 241142384Sharti SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_DLE | SUNI_REGM_MCTRL_LOOPT, 242142384Sharti val); 243142384Sharti if (err) 244142384Sharti return (err); 245142384Sharti utp->loopback = mode; 246142384Sharti 247142384Sharti return (0); 248142384Sharti} 249142384Sharti 250142384Sharti/* 251142384Sharti * Update statistics from a SUNI/LITE or SUNI/ULTRA 252142384Sharti */ 253142384Shartistatic void 254142384Shartisuni_lite_update_stats(struct utopia *utp) 255142384Sharti{ 256142384Sharti int err; 257142384Sharti 258142384Sharti /* write to the master if we can */ 259142384Sharti if (!(utp->flags & UTP_FL_NORESET)) { 260142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_MRESET, 0, 0); 261142384Sharti } else { 262142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_RSOP_BIP8, 0, 0); 263142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RLOPBIP8_24, 0, 0); 264142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RPOPBIP8, 0, 0); 265142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RACPCHCS, 0, 0); 266142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_TACPCNT, 0, 0); 267142384Sharti 268142384Sharti } 269142384Sharti if (err) { 270142384Sharti#ifdef DIAGNOSTIC 271142384Sharti printf("%s: register write error %s: %d\n", __func__, 272142384Sharti utp->chip->name, err); 273142384Sharti#endif 274142384Sharti return; 275142384Sharti } 276142384Sharti 277142384Sharti DELAY(8); 278142384Sharti 279142384Sharti utp->stats.rx_sbip += utopia_update(utp, 280142384Sharti SUNI_REGO_RSOP_BIP8, 2, 0xffff); 281142384Sharti utp->stats.rx_lbip += utopia_update(utp, 282142384Sharti SUNI_REGO_RLOPBIP8_24, 3, 0xfffff); 283142384Sharti utp->stats.rx_lfebe += utopia_update(utp, 284142384Sharti SUNI_REGO_RLOPFEBE, 3, 0xfffff); 285142384Sharti utp->stats.rx_pbip += utopia_update(utp, 286142384Sharti SUNI_REGO_RPOPBIP8, 2, 0xffff); 287142384Sharti utp->stats.rx_pfebe += utopia_update(utp, 288142384Sharti SUNI_REGO_RPOPFEBE, 2, 0xffff); 289142384Sharti utp->stats.rx_corr += utopia_update(utp, 290142384Sharti SUNI_REGO_RACPCHCS, 1, 0xff); 291142384Sharti utp->stats.rx_uncorr += utopia_update(utp, 292142384Sharti SUNI_REGO_RACPUHCS, 1, 0xff); 293142384Sharti utp->stats.rx_cells += utopia_update(utp, 294142384Sharti SUNI_REGO_RACPCNT, 3, 0x7ffff); 295142384Sharti utp->stats.tx_cells += utopia_update(utp, 296142384Sharti SUNI_REGO_TACPCNT, 3, 0x7ffff); 297142384Sharti} 298142384Sharti 299142384Sharti/* 300142384Sharti * Handle interrupt on SUNI chip 301142384Sharti */ 302142384Shartistatic void 303142384Shartisuni_intr_default(struct utopia *utp) 304142384Sharti{ 305142384Sharti uint8_t regs[SUNI_REGO_MTEST]; 306142384Sharti u_int n = SUNI_REGO_MTEST; 307142384Sharti int err; 308142384Sharti 309142384Sharti /* Read all registers. This acks the interrupts */ 310142384Sharti if ((err = UTP_READREGS(utp, SUNI_REGO_MRESET, regs, &n)) != 0) { 311142384Sharti printf("SUNI read error %d\n", err); 312142384Sharti return; 313142384Sharti } 314142384Sharti if (n <= SUNI_REGO_RSOPSIS) { 315142384Sharti printf("%s: could not read RSOPSIS", __func__); 316142384Sharti return; 317142384Sharti } 318142384Sharti /* check for LOSI (loss of signal) */ 319142384Sharti if ((regs[SUNI_REGO_MISTATUS] & SUNI_REGM_MISTATUS_RSOPI) && 320142384Sharti (regs[SUNI_REGO_RSOPSIS] & SUNI_REGM_RSOPSIS_LOSI)) 321142384Sharti utopia_check_carrier(utp, !(regs[SUNI_REGO_RSOPSIS] 322142384Sharti & SUNI_REGM_RSOPSIS_LOSV)); 323142384Sharti} 324142384Sharti 325142384Sharticonst struct utopia_chip utopia_chip_lite = { 326142384Sharti UTP_TYPE_SUNI_LITE, 327142384Sharti "Suni/Lite (PMC-5346)", 328142384Sharti 256, 329142384Sharti suni_reset_default, 330142384Sharti suni_set_sdh, 331142384Sharti suni_set_unass, 332142384Sharti suni_set_noscramb, 333142384Sharti suni_update_carrier, 334142384Sharti suni_set_loopback_lite, 335142384Sharti suni_intr_default, 336142384Sharti suni_lite_update_stats, 337142384Sharti}; 338142384Sharti 339142384Sharti/* 340142384Sharti * Set loopback mode for the Ultra 341142384Sharti */ 342142384Shartistatic int 343142384Shartisuni_set_loopback_ultra(struct utopia *utp, u_int mode) 344142384Sharti{ 345142384Sharti int err; 346142384Sharti uint32_t val; 347142384Sharti u_int nmode; 348142384Sharti 349142384Sharti val = 0; 350142384Sharti nmode = mode; 351142384Sharti if (mode & UTP_LOOP_TIME) { 352142384Sharti nmode &= ~UTP_LOOP_TIME; 353142384Sharti val |= SUNI_REGM_MCTRL_LOOPT; 354142384Sharti } 355142384Sharti if (mode & UTP_LOOP_DIAG) { 356142384Sharti nmode &= ~UTP_LOOP_DIAG; 357142384Sharti if (val & SUNI_REGM_MCTRL_LOOPT) 358142384Sharti return (EINVAL); 359142384Sharti val |= SUNI_REGM_MCTRL_SDLE; 360142384Sharti } 361142384Sharti if (mode & UTP_LOOP_LINE) { 362142384Sharti nmode &= ~UTP_LOOP_LINE; 363142384Sharti if (val & (SUNI_REGM_MCTRL_LOOPT | SUNI_REGM_MCTRL_SDLE)) 364142384Sharti return (EINVAL); 365142384Sharti val |= SUNI_REGM_MCTRL_LLE; 366142384Sharti } 367142384Sharti if (mode & UTP_LOOP_PARAL) { 368142384Sharti nmode &= ~UTP_LOOP_PARAL; 369142384Sharti val |= SUNI_REGM_MCTRL_PDLE; 370142384Sharti } 371142384Sharti if (mode & UTP_LOOP_TWIST) { 372142384Sharti nmode &= ~UTP_LOOP_TWIST; 373142384Sharti val |= SUNI_REGM_MCTRL_TPLE; 374142384Sharti } 375142384Sharti if (nmode != 0) 376142384Sharti return (EINVAL); 377142384Sharti 378142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_MCTRL, 379142384Sharti SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_SDLE | SUNI_REGM_MCTRL_LOOPT | 380142384Sharti SUNI_REGM_MCTRL_PDLE | SUNI_REGM_MCTRL_TPLE, val); 381142384Sharti if (err) 382142384Sharti return (err); 383142384Sharti utp->loopback = mode; 384142384Sharti 385142384Sharti return (0); 386142384Sharti} 387142384Sharti 388142384Sharticonst struct utopia_chip utopia_chip_ultra = { 389142384Sharti UTP_TYPE_SUNI_ULTRA, 390142384Sharti "Suni/Ultra (PMC-5350)", 391142384Sharti 256, 392142384Sharti suni_reset_default, 393142384Sharti suni_set_sdh, 394142384Sharti suni_set_unass, 395142384Sharti suni_set_noscramb, 396142384Sharti suni_update_carrier, 397142384Sharti suni_set_loopback_ultra, 398142384Sharti suni_intr_default, 399142384Sharti suni_lite_update_stats, 400142384Sharti}; 401142384Sharti 402142384Sharti/* 403142384Sharti * Set loopback mode for the 622 404142384Sharti */ 405142384Shartistatic int 406142384Shartisuni_set_loopback_622(struct utopia *utp, u_int mode) 407142384Sharti{ 408142384Sharti int err; 409142384Sharti uint32_t val; 410142384Sharti uint8_t config; 411142384Sharti int smode; 412142384Sharti u_int nmode; 413142384Sharti u_int n = 1; 414142384Sharti 415142384Sharti val = 0; 416142384Sharti nmode = mode; 417142384Sharti if (mode & UTP_LOOP_PATH) { 418142384Sharti nmode &= ~UTP_LOOP_PATH; 419142384Sharti val |= SUNI_REGM_MCTRLM_DPLE; 420142384Sharti } 421142384Sharti 422142384Sharti err = UTP_READREGS(utp, SUNI_REGO_MCONFIG, &config, &n); 423142384Sharti if (err != 0) 424142384Sharti return (err); 425142384Sharti smode = ((config & SUNI_REGM_MCONFIG_TMODE_622) == 426142384Sharti SUNI_REGM_MCONFIG_TMODE_STS1_BIT && 427142384Sharti (config & SUNI_REGM_MCONFIG_RMODE_622) == 428142384Sharti SUNI_REGM_MCONFIG_RMODE_STS1_BIT); 429142384Sharti 430142384Sharti if (mode & UTP_LOOP_TIME) { 431142384Sharti if (!smode) 432142384Sharti return (EINVAL); 433142384Sharti nmode &= ~UTP_LOOP_TIME; 434142384Sharti val |= SUNI_REGM_MCTRLM_LOOPT; 435142384Sharti } 436142384Sharti if (mode & UTP_LOOP_DIAG) { 437142384Sharti nmode &= ~UTP_LOOP_DIAG; 438142384Sharti if (val & SUNI_REGM_MCTRLM_LOOPT) 439142384Sharti return (EINVAL); 440142384Sharti val |= SUNI_REGM_MCTRLM_DLE; 441142384Sharti } 442142384Sharti if (mode & UTP_LOOP_LINE) { 443142384Sharti nmode &= ~UTP_LOOP_LINE; 444142384Sharti if (val & (SUNI_REGM_MCTRLM_LOOPT | SUNI_REGM_MCTRLM_DLE)) 445142384Sharti return (EINVAL); 446142384Sharti val |= SUNI_REGM_MCTRLM_LLE; 447142384Sharti } 448142384Sharti if (nmode != 0) 449142384Sharti return (EINVAL); 450142384Sharti 451142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_MCTRLM, 452142384Sharti SUNI_REGM_MCTRLM_LLE | SUNI_REGM_MCTRLM_DLE | 453142384Sharti SUNI_REGM_MCTRLM_DPLE | SUNI_REGM_MCTRL_LOOPT, val); 454142384Sharti if (err) 455142384Sharti return (err); 456142384Sharti utp->loopback = mode; 457142384Sharti 458142384Sharti return (0); 459142384Sharti} 460142384Sharti 461142384Sharti/* 462142384Sharti * Reset the SUNI chip to reflect the current state of utopia. 463142384Sharti */ 464142384Shartistatic int 465142384Shartisuni_reset_622(struct utopia *utp) 466142384Sharti{ 467142384Sharti int err = 0; 468142384Sharti 469142384Sharti if (!(utp->flags & UTP_FL_NORESET)) { 470142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, 471142384Sharti SUNI_REGM_MRESET_RESET, SUNI_REGM_MRESET_RESET); 472142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, 473142384Sharti SUNI_REGM_MRESET_RESET, 0); 474142384Sharti } 475142384Sharti 476142384Sharti /* disable test mode */ 477142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_MTEST, 0xff, 478142384Sharti SUNI_REGM_MTEST_DS27_53_622); 479142384Sharti 480142384Sharti err |= suni_set_chip(utp); 481142384Sharti 482142384Sharti return (err ? EIO : 0); 483142384Sharti} 484142384Sharti 485142384Sharti/* 486142384Sharti * Update statistics from a SUNI/622 487142384Sharti */ 488142384Shartistatic void 489142384Shartisuni_622_update_stats(struct utopia *utp) 490142384Sharti{ 491142384Sharti int err; 492142384Sharti 493142384Sharti /* write to the master if we can */ 494142384Sharti if (!(utp->flags & UTP_FL_NORESET)) { 495142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_MRESET, 0, 0); 496142384Sharti } else { 497142384Sharti err = UTP_WRITEREG(utp, SUNI_REGO_RSOP_BIP8, 0, 0); 498142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RLOPBIP8_24, 0, 0); 499142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RPOPBIP8, 0, 0); 500142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_RACPCHCS, 0, 0); 501142384Sharti err |= UTP_WRITEREG(utp, SUNI_REGO_TACPCNT, 0, 0); 502142384Sharti } 503142384Sharti if (err) { 504142384Sharti#ifdef DIAGNOSTIC 505142384Sharti printf("%s: register write error %s: %d\n", __func__, 506142384Sharti utp->chip->name, err); 507142384Sharti#endif 508142384Sharti return; 509142384Sharti } 510142384Sharti 511142384Sharti DELAY(8); 512142384Sharti 513142384Sharti utp->stats.rx_sbip += utopia_update(utp, 514142384Sharti SUNI_REGO_RSOP_BIP8, 2, 0xffff); 515142384Sharti utp->stats.rx_lbip += utopia_update(utp, 516142384Sharti SUNI_REGO_RLOPBIP8_24, 3, 0xfffff); 517142384Sharti utp->stats.rx_lfebe += utopia_update(utp, 518142384Sharti SUNI_REGO_RLOPFEBE, 3, 0xfffff); 519142384Sharti utp->stats.rx_pbip += utopia_update(utp, 520142384Sharti SUNI_REGO_RPOPBIP8, 2, 0xffff); 521142384Sharti utp->stats.rx_pfebe += utopia_update(utp, 522142384Sharti SUNI_REGO_RPOPFEBE, 2, 0xffff); 523142384Sharti utp->stats.rx_corr += utopia_update(utp, 524142384Sharti SUNI_REGO_RACPCHCS_622, 2, 0xfff); 525142384Sharti utp->stats.rx_uncorr += utopia_update(utp, 526142384Sharti SUNI_REGO_RACPUHCS_622, 2, 0xfff); 527142384Sharti utp->stats.rx_cells += utopia_update(utp, 528142384Sharti SUNI_REGO_RACPCNT_622, 3, 0x1fffff); 529142384Sharti utp->stats.tx_cells += utopia_update(utp, 530142384Sharti SUNI_REGO_TACPCNT, 3, 0x1fffff); 531142384Sharti} 532142384Sharti 533142384Sharticonst struct utopia_chip utopia_chip_622 = { 534142384Sharti UTP_TYPE_SUNI_622, 535142384Sharti "Suni/622 (PMC-5355)", 536142384Sharti 256, 537142384Sharti suni_reset_622, 538142384Sharti suni_set_sdh, 539142384Sharti suni_set_unass, 540142384Sharti suni_set_noscramb, 541142384Sharti suni_update_carrier, 542142384Sharti suni_set_loopback_622, 543142384Sharti suni_intr_default, 544142384Sharti suni_622_update_stats, 545142384Sharti}; 546