From 272c3271b3f9a21aa6a10e9806830288c1eb6212 Mon Sep 17 00:00:00 2001 From: harti Date: Thu, 24 Feb 2005 16:56:36 +0000 Subject: [PATCH] Split the chip-specific code from the generic Utopia code. This simplifies adding of new physical chips. Now one just needs to add a .h and a .c file for the new chip and add one line to utopia.c for that chip. --- sys/conf/files | 2 + sys/dev/utopia/idtphy.c | 494 ++++++++++++++++++ sys/dev/utopia/suni.c | 545 ++++++++++++++++++++ sys/dev/utopia/utopia.c | 954 ++--------------------------------- sys/dev/utopia/utopia.h | 4 +- sys/dev/utopia/utopia_priv.h | 46 ++ 6 files changed, 1122 insertions(+), 923 deletions(-) create mode 100644 sys/dev/utopia/idtphy.c create mode 100644 sys/dev/utopia/suni.c create mode 100644 sys/dev/utopia/utopia_priv.h diff --git a/sys/conf/files b/sys/conf/files index 1a9c67453559..22d35e429b56 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -863,6 +863,8 @@ dev/usb/usbdi_util.c optional usb dev/usb/uscanner.c optional uscanner dev/usb/uvisor.c optional uvisor ucom dev/usb/uvscom.c optional uvscom ucom +dev/utopia/idtphy.c optional utopia +dev/utopia/suni.c optional utopia dev/utopia/utopia.c optional utopia dev/vge/if_vge.c optional vge dev/vkbd/vkbd.c optional vkbd diff --git a/sys/dev/utopia/idtphy.c b/sys/dev/utopia/idtphy.c new file mode 100644 index 000000000000..5aaa576abb23 --- /dev/null +++ b/sys/dev/utopia/idtphy.c @@ -0,0 +1,494 @@ +/*- + * Copyright (c) 2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Hartmut Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* + * Reset IDT77105. There is really no way to reset this thing by acessing + * the registers. Load the registers with default values. + */ +static int +idt77105_reset(struct utopia *utp) +{ + int err = 0; + u_int n; + uint8_t val[2]; + + err |= UTP_WRITEREG(utp, IDTPHY_REGO_MCR, 0xff, + IDTPHY_REGM_MCR_DRIC | IDTPHY_REGM_MCR_EI); + n = 1; + err |= UTP_READREGS(utp, IDTPHY_REGO_ISTAT, val, &n); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_DIAG, 0xff, 0); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_LHEC, 0xff, 0); + + err |= UTP_WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_SEC); + n = 2; + err |= UTP_READREGS(utp, IDTPHY_REGO_CNT, val, &n); + + err |= UTP_WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_TX); + n = 2; + err |= UTP_READREGS(utp, IDTPHY_REGO_CNT, val, &n); + + err |= UTP_WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_RX); + n = 2; + err |= UTP_READREGS(utp, IDTPHY_REGO_CNT, val, &n); + + err |= UTP_WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_HECE); + n = 2; + err |= UTP_READREGS(utp, IDTPHY_REGO_CNT, val, &n); + + err |= UTP_WRITEREG(utp, IDTPHY_REGO_MCR, IDTPHY_REGM_MCR_DREC, + IDTPHY_REGM_MCR_DREC); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_DIAG, IDTPHY_REGM_DIAG_RFLUSH, + IDTPHY_REGM_DIAG_RFLUSH); + + /* loopback */ + err |= utopia_set_loopback(utp, utp->loopback); + + /* update carrier state */ + err |= utopia_update_carrier(utp); + + return (err ? EIO : 0); +} + +static int +idt77105_inval(struct utopia *utp, int what __unused) +{ + + return (EINVAL); +} + +static int +idt77105_update_carrier(struct utopia *utp) +{ + int err; + uint8_t reg; + u_int n = 1; + + if ((err = UTP_READREGS(utp, IDTPHY_REGO_ISTAT, ®, &n)) != 0) { + utp->carrier = UTP_CARR_UNKNOWN; + return (err); + } + utopia_check_carrier(utp, reg & IDTPHY_REGM_ISTAT_GOOD); + return (0); +} + +static int +idt77105_set_loopback(struct utopia *utp, u_int mode) +{ + int err; + + switch (mode) { + case UTP_LOOP_NONE: + err = UTP_WRITEREG(utp, IDTPHY_REGO_DIAG, + IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_NONE); + break; + + case UTP_LOOP_DIAG: + err = UTP_WRITEREG(utp, IDTPHY_REGO_DIAG, + IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_PHY); + break; + + case UTP_LOOP_LINE: + err = UTP_WRITEREG(utp, IDTPHY_REGO_DIAG, + IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_LINE); + break; + + default: + return (EINVAL); + } + if (err) + return (err); + utp->loopback = mode; + return (0); +} + +/* + * Handle interrupt on IDT77105 chip + */ +static void +idt77105_intr(struct utopia *utp) +{ + uint8_t reg; + u_int n = 1; + int err; + + /* Interrupt status and ack the interrupt */ + if ((err = UTP_READREGS(utp, IDTPHY_REGO_ISTAT, ®, &n)) != 0) { + printf("IDT77105 read error %d\n", err); + return; + } + /* check for signal condition */ + utopia_check_carrier(utp, reg & IDTPHY_REGM_ISTAT_GOOD); +} + +static void +idt77105_update_stats(struct utopia *utp) +{ + int err = 0; + uint8_t regs[2]; + u_int n; + +#ifdef DIAGNOSTIC +#define UDIAG(F,A,B) printf(F, A, B) +#else +#define UDIAG(F,A,B) do { } while (0) +#endif + +#define UPD(FIELD, CODE, N, MASK) \ + err = UTP_WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, CODE); \ + if (err != 0) { \ + UDIAG("%s: cannot write CNTS: %d\n", __func__, err); \ + return; \ + } \ + n = N; \ + err = UTP_READREGS(utp, IDTPHY_REGO_CNT, regs, &n); \ + if (err != 0) { \ + UDIAG("%s: cannot read CNT: %d\n", __func__, err); \ + return; \ + } \ + if (n != N) { \ + UDIAG("%s: got only %u registers\n", __func__, n); \ + return; \ + } \ + if (N == 1) \ + utp->stats.FIELD += (regs[0] & MASK); \ + else \ + utp->stats.FIELD += (regs[0] | (regs[1] << 8)) & MASK; + + UPD(rx_symerr, IDTPHY_REGM_CNTS_SEC, 1, 0xff); + UPD(tx_cells, IDTPHY_REGM_CNTS_TX, 2, 0xffff); + UPD(rx_cells, IDTPHY_REGM_CNTS_RX, 2, 0xffff); + UPD(rx_uncorr, IDTPHY_REGM_CNTS_HECE, 1, 0x1f); + +#undef UDIAG +#undef UPD +} + +struct utopia_chip utopia_chip_idt77105 = { + UTP_TYPE_IDT77105, + "IDT77105", + 7, + idt77105_reset, + idt77105_inval, + idt77105_inval, + idt77105_inval, + idt77105_update_carrier, + idt77105_set_loopback, + idt77105_intr, + idt77105_update_stats, +}; + +/* + * Update the carrier status + */ +static int +idt77155_update_carrier(struct utopia *utp) +{ + int err; + uint8_t reg; + u_int n = 1; + + if ((err = UTP_READREGS(utp, IDTPHY_REGO_RSOS, ®, &n)) != 0) { + utp->carrier = UTP_CARR_UNKNOWN; + return (err); + } + utopia_check_carrier(utp, !(reg & IDTPHY_REGM_RSOS_LOS)); + return (0); +} + +/* + * Handle interrupt on IDT77155 chip + */ +static void +idt77155_intr(struct utopia *utp) +{ + uint8_t reg; + u_int n = 1; + int err; + + if ((err = UTP_READREGS(utp, IDTPHY_REGO_RSOS, ®, &n)) != 0) { + printf("IDT77105 read error %d\n", err); + return; + } + utopia_check_carrier(utp, !(reg & IDTPHY_REGM_RSOS_LOS)); +} + +/* + * set SONET/SDH mode + */ +static int +idt77155_set_sdh(struct utopia *utp, int sdh) +{ + int err; + + if (sdh) + err = UTP_WRITEREG(utp, IDTPHY_REGO_PTRM, + IDTPHY_REGM_PTRM_SS, IDTPHY_REGM_PTRM_SDH); + else + err = UTP_WRITEREG(utp, IDTPHY_REGO_PTRM, + IDTPHY_REGM_PTRM_SS, IDTPHY_REGM_PTRM_SONET); + if (err != 0) + return (err); + + utp->state &= ~UTP_ST_SDH; + if (sdh) + utp->state |= UTP_ST_SDH; + + return (0); +} + +/* + * set idle/unassigned cells + */ +static int +idt77155_set_unass(struct utopia *utp, int unass) +{ + int err; + + if (unass) + err = UTP_WRITEREG(utp, IDTPHY_REGO_TCHP, 0xff, 0); + else + err = UTP_WRITEREG(utp, IDTPHY_REGO_TCHP, 0xff, 1); + if (err != 0) + return (err); + + utp->state &= ~UTP_ST_UNASS; + if (unass) + utp->state |= UTP_ST_UNASS; + + return (0); +} + +/* + * enable/disable scrambling + */ +static int +idt77155_set_noscramb(struct utopia *utp, int noscramb) +{ + int err; + + if (noscramb) { + err = UTP_WRITEREG(utp, IDTPHY_REGO_TCC, + IDTPHY_REGM_TCC_DSCR, IDTPHY_REGM_TCC_DSCR); + if (err) + return (err); + err = UTP_WRITEREG(utp, IDTPHY_REGO_RCC, + IDTPHY_REGM_RCC_DSCR, IDTPHY_REGM_RCC_DSCR); + if (err) + return (err); + utp->state |= UTP_ST_NOSCRAMB; + } else { + err = UTP_WRITEREG(utp, IDTPHY_REGO_TCC, + IDTPHY_REGM_TCC_DSCR, 0); + if (err) + return (err); + err = UTP_WRITEREG(utp, IDTPHY_REGO_RCC, + IDTPHY_REGM_RCC_DSCR, 0); + if (err) + return (err); + utp->state &= ~UTP_ST_NOSCRAMB; + } + return (0); +} + +/* + * Set loopback mode for the 77155 + */ +static int +idt77155_set_loopback(struct utopia *utp, u_int mode) +{ + int err; + uint32_t val; + u_int nmode; + + val = 0; + nmode = mode; + if (mode & UTP_LOOP_TIME) { + nmode &= ~UTP_LOOP_TIME; + val |= IDTPHY_REGM_MCTL_TLOOP; + } + if (mode & UTP_LOOP_DIAG) { + nmode &= ~UTP_LOOP_DIAG; + val |= IDTPHY_REGM_MCTL_DLOOP; + } + if (mode & UTP_LOOP_LINE) { + nmode &= ~UTP_LOOP_LINE; + val |= IDTPHY_REGM_MCTL_LLOOP; + } + if (nmode != 0) + return (EINVAL); + + err = UTP_WRITEREG(utp, IDTPHY_REGO_MCTL, IDTPHY_REGM_MCTL_TLOOP | + IDTPHY_REGM_MCTL_DLOOP | IDTPHY_REGM_MCTL_LLOOP, val); + if (err) + return (err); + utp->loopback = mode; + + return (0); +} + +/* + * Set the chip to reflect the current state in utopia. + * Assume, that the chip has been reset. + */ +static int +idt77155_set_chip(struct utopia *utp) +{ + int err = 0; + + /* set sonet/sdh */ + err |= idt77155_set_sdh(utp, utp->state & UTP_ST_SDH); + + /* unassigned or idle cells */ + err |= idt77155_set_unass(utp, utp->state & UTP_ST_UNASS); + + /* loopback */ + err |= idt77155_set_loopback(utp, utp->loopback); + + /* update carrier state */ + err |= idt77155_update_carrier(utp); + + /* enable interrupts on LOS */ + err |= UTP_WRITEREG(utp, IDTPHY_REGO_INT, + IDTPHY_REGM_INT_RXSOHI, IDTPHY_REGM_INT_RXSOHI); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_RSOC, + IDTPHY_REGM_RSOC_LOSI, IDTPHY_REGM_RSOC_LOSI); + + return (err ? EIO : 0); +} + +/* + * Reset the chip to reflect the current state of utopia. + */ +static int +idt77155_reset(struct utopia *utp) +{ + int err = 0; + + if (!(utp->flags & UTP_FL_NORESET)) { + err |= UTP_WRITEREG(utp, IDTPHY_REGO_MRID, + IDTPHY_REGM_MRID_RESET, IDTPHY_REGM_MRID_RESET); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_MRID, + IDTPHY_REGM_MRID_RESET, 0); + } + + err |= idt77155_set_chip(utp); + + return (err ? EIO : 0); +} + +/* + * Update statistics from a IDT77155 + * This appears to be the same as for the Suni/Lite and Ultra. IDT however + * makes no assessment about the transfer time. Assume 7us. + */ +static void +idt77155_update_stats(struct utopia *utp) +{ + int err; + + /* write to the master if we can */ + if (!(utp->flags & UTP_FL_NORESET)) { + err = UTP_WRITEREG(utp, IDTPHY_REGO_MRID, 0, 0); + } else { + err = UTP_WRITEREG(utp, IDTPHY_REGO_BIPC, 0, 0); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_B2EC, 0, 0); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_B3EC, 0, 0); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_CEC, 0, 0); + err |= UTP_WRITEREG(utp, IDTPHY_REGO_TXCNT, 0, 0); + + } + if (err) { +#ifdef DIAGNOSTIC + printf("%s: register write error %s: %d\n", __func__, + utp->chip->name, err); +#endif + return; + } + + DELAY(8); + + utp->stats.rx_sbip += utopia_update(utp, + IDTPHY_REGO_BIPC, 2, 0xffff); + utp->stats.rx_lbip += utopia_update(utp, + IDTPHY_REGO_B2EC, 3, 0xfffff); + utp->stats.rx_lfebe += utopia_update(utp, + IDTPHY_REGO_FEBEC, 3, 0xfffff); + utp->stats.rx_pbip += utopia_update(utp, + IDTPHY_REGO_B3EC, 2, 0xffff); + utp->stats.rx_pfebe += utopia_update(utp, + IDTPHY_REGO_PFEBEC, 2, 0xffff); + utp->stats.rx_corr += utopia_update(utp, + IDTPHY_REGO_CEC, 1, 0xff); + utp->stats.rx_uncorr += utopia_update(utp, + IDTPHY_REGO_UEC, 1, 0xff); + utp->stats.rx_cells += utopia_update(utp, + IDTPHY_REGO_RCCNT, 3, 0x7ffff); + utp->stats.tx_cells += utopia_update(utp, + IDTPHY_REGO_TXCNT, 3, 0x7ffff); +} + +const struct utopia_chip utopia_chip_idt77155 = { + UTP_TYPE_IDT77155, + "IDT77155", + 0x80, + idt77155_reset, + idt77155_set_sdh, + idt77155_set_unass, + idt77155_set_noscramb, + idt77155_update_carrier, + idt77155_set_loopback, + idt77155_intr, + idt77155_update_stats, +}; diff --git a/sys/dev/utopia/suni.c b/sys/dev/utopia/suni.c new file mode 100644 index 000000000000..ffc49e8e84da --- /dev/null +++ b/sys/dev/utopia/suni.c @@ -0,0 +1,545 @@ +/*- + * Copyright (c) 2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Author: Hartmut Brandt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* + * set SONET/SDH mode + */ +static int +suni_set_sdh(struct utopia *utp, int sdh) +{ + int err; + + if (sdh) + err = UTP_WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1, + SUNI_REGM_TPOPAPTR_S, + SUNI_REGM_SDH << SUNI_REGS_TPOPAPTR_S); + else + err = UTP_WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1, + SUNI_REGM_TPOPAPTR_S, + SUNI_REGM_SONET << SUNI_REGS_TPOPAPTR_S); + if (err != 0) + return (err); + + utp->state &= ~UTP_ST_SDH; + if (sdh) + utp->state |= UTP_ST_SDH; + + return (0); +} + +/* + * set idle/unassigned cells + */ +static int +suni_set_unass(struct utopia *utp, int unass) +{ + int err; + + if (unass) + err = UTP_WRITEREG(utp, SUNI_REGO_TACPIDLEH, + 0xff, (0 << SUNI_REGS_TACPIDLEH_CLP)); + else + err = UTP_WRITEREG(utp, SUNI_REGO_TACPIDLEH, + 0xff, (1 << SUNI_REGS_TACPIDLEH_CLP)); + if (err != 0) + return (err); + + utp->state &= ~UTP_ST_UNASS; + if (unass) + utp->state |= UTP_ST_UNASS; + + return (0); +} + +/* + * enable/disable scrambling + */ +static int +suni_set_noscramb(struct utopia *utp, int noscramb) +{ + int err; + + if (noscramb) { + err = UTP_WRITEREG(utp, SUNI_REGO_TACPCTRL, + SUNI_REGM_TACPCTRL_DSCR, SUNI_REGM_TACPCTRL_DSCR); + if (err) + return (err); + err = UTP_WRITEREG(utp, SUNI_REGO_RACPCTRL, + SUNI_REGM_RACPCTRL_DDSCR, SUNI_REGM_RACPCTRL_DDSCR); + if (err) + return (err); + utp->state |= UTP_ST_NOSCRAMB; + } else { + err = UTP_WRITEREG(utp, SUNI_REGO_TACPCTRL, + SUNI_REGM_TACPCTRL_DSCR, 0); + if (err) + return (err); + err = UTP_WRITEREG(utp, SUNI_REGO_RACPCTRL, + SUNI_REGM_RACPCTRL_DDSCR, 0); + if (err) + return (err); + utp->state &= ~UTP_ST_NOSCRAMB; + } + return (0); +} + +/* + * Get current carrier state + */ +static int +suni_update_carrier(struct utopia *utp) +{ + int err; + uint8_t reg; + u_int n = 1; + + if ((err = UTP_READREGS(utp, SUNI_REGO_RSOPSIS, ®, &n)) != 0) { + utp->carrier = UTP_CARR_UNKNOWN; + return (err); + } + utopia_check_carrier(utp, !(reg & SUNI_REGM_RSOPSIS_LOSV)); + return (0); +} + +/* + * Set the SUNI chip to reflect the current state in utopia. + * Assume, that the chip has been reset. + */ +static int +suni_set_chip(struct utopia *utp) +{ + int err = 0; + + /* set sonet/sdh */ + err |= utopia_set_sdh(utp, utp->state & UTP_ST_SDH); + + /* unassigned or idle cells */ + err |= utopia_set_unass(utp, utp->state & UTP_ST_UNASS); + err |= UTP_WRITEREG(utp, SUNI_REGO_TACPIDLEP, 0xff, 0x6a); + + /* set scrambling */ + err |= utopia_set_noscramb(utp, utp->state & UTP_ST_NOSCRAMB); + + /* loopback */ + err |= utopia_set_loopback(utp, utp->loopback); + + /* update carrier state */ + err |= utopia_update_carrier(utp); + + /* enable interrupts on LOS */ + err |= UTP_WRITEREG(utp, SUNI_REGO_RSOPCIE, + SUNI_REGM_RSOPCIE_LOSE, SUNI_REGM_RSOPCIE_LOSE); + + return (err ? EIO : 0); +} + +/* + * Reset the SUNI chip to reflect the current state of utopia. + */ +static int +suni_reset_default(struct utopia *utp) +{ + int err = 0; + + if (!(utp->flags & UTP_FL_NORESET)) { + err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, + SUNI_REGM_MRESET_RESET, SUNI_REGM_MRESET_RESET); + err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, + SUNI_REGM_MRESET_RESET, 0); + } + + /* disable test mode */ + err |= UTP_WRITEREG(utp, SUNI_REGO_MTEST, 0xff, 0x00); + + err |= suni_set_chip(utp); + + return (err ? EIO : 0); +} + +/* + * Set loopback mode for the Lite + */ +static int +suni_set_loopback_lite(struct utopia *utp, u_int mode) +{ + int err; + uint32_t val; + u_int nmode; + + val = 0; + nmode = mode; + if (mode & UTP_LOOP_TIME) { + nmode &= ~UTP_LOOP_TIME; + val |= SUNI_REGM_MCTRL_LOOPT; + } + if (mode & UTP_LOOP_DIAG) { + nmode &= ~UTP_LOOP_DIAG; + val |= SUNI_REGM_MCTRL_DLE; + } + if (mode & UTP_LOOP_LINE) { + nmode &= ~UTP_LOOP_LINE; + if (val & SUNI_REGM_MCTRL_DLE) + return (EINVAL); + val |= SUNI_REGM_MCTRL_LLE; + } + if (nmode != 0) + return (EINVAL); + + err = UTP_WRITEREG(utp, SUNI_REGO_MCTRL, + SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_DLE | SUNI_REGM_MCTRL_LOOPT, + val); + if (err) + return (err); + utp->loopback = mode; + + return (0); +} + +/* + * Update statistics from a SUNI/LITE or SUNI/ULTRA + */ +static void +suni_lite_update_stats(struct utopia *utp) +{ + int err; + + /* write to the master if we can */ + if (!(utp->flags & UTP_FL_NORESET)) { + err = UTP_WRITEREG(utp, SUNI_REGO_MRESET, 0, 0); + } else { + err = UTP_WRITEREG(utp, SUNI_REGO_RSOP_BIP8, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_RLOPBIP8_24, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_RPOPBIP8, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_RACPCHCS, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_TACPCNT, 0, 0); + + } + if (err) { +#ifdef DIAGNOSTIC + printf("%s: register write error %s: %d\n", __func__, + utp->chip->name, err); +#endif + return; + } + + DELAY(8); + + utp->stats.rx_sbip += utopia_update(utp, + SUNI_REGO_RSOP_BIP8, 2, 0xffff); + utp->stats.rx_lbip += utopia_update(utp, + SUNI_REGO_RLOPBIP8_24, 3, 0xfffff); + utp->stats.rx_lfebe += utopia_update(utp, + SUNI_REGO_RLOPFEBE, 3, 0xfffff); + utp->stats.rx_pbip += utopia_update(utp, + SUNI_REGO_RPOPBIP8, 2, 0xffff); + utp->stats.rx_pfebe += utopia_update(utp, + SUNI_REGO_RPOPFEBE, 2, 0xffff); + utp->stats.rx_corr += utopia_update(utp, + SUNI_REGO_RACPCHCS, 1, 0xff); + utp->stats.rx_uncorr += utopia_update(utp, + SUNI_REGO_RACPUHCS, 1, 0xff); + utp->stats.rx_cells += utopia_update(utp, + SUNI_REGO_RACPCNT, 3, 0x7ffff); + utp->stats.tx_cells += utopia_update(utp, + SUNI_REGO_TACPCNT, 3, 0x7ffff); +} + +/* + * Handle interrupt on SUNI chip + */ +static void +suni_intr_default(struct utopia *utp) +{ + uint8_t regs[SUNI_REGO_MTEST]; + u_int n = SUNI_REGO_MTEST; + int err; + + /* Read all registers. This acks the interrupts */ + if ((err = UTP_READREGS(utp, SUNI_REGO_MRESET, regs, &n)) != 0) { + printf("SUNI read error %d\n", err); + return; + } + if (n <= SUNI_REGO_RSOPSIS) { + printf("%s: could not read RSOPSIS", __func__); + return; + } + /* check for LOSI (loss of signal) */ + if ((regs[SUNI_REGO_MISTATUS] & SUNI_REGM_MISTATUS_RSOPI) && + (regs[SUNI_REGO_RSOPSIS] & SUNI_REGM_RSOPSIS_LOSI)) + utopia_check_carrier(utp, !(regs[SUNI_REGO_RSOPSIS] + & SUNI_REGM_RSOPSIS_LOSV)); +} + +const struct utopia_chip utopia_chip_lite = { + UTP_TYPE_SUNI_LITE, + "Suni/Lite (PMC-5346)", + 256, + suni_reset_default, + suni_set_sdh, + suni_set_unass, + suni_set_noscramb, + suni_update_carrier, + suni_set_loopback_lite, + suni_intr_default, + suni_lite_update_stats, +}; + +/* + * Set loopback mode for the Ultra + */ +static int +suni_set_loopback_ultra(struct utopia *utp, u_int mode) +{ + int err; + uint32_t val; + u_int nmode; + + val = 0; + nmode = mode; + if (mode & UTP_LOOP_TIME) { + nmode &= ~UTP_LOOP_TIME; + val |= SUNI_REGM_MCTRL_LOOPT; + } + if (mode & UTP_LOOP_DIAG) { + nmode &= ~UTP_LOOP_DIAG; + if (val & SUNI_REGM_MCTRL_LOOPT) + return (EINVAL); + val |= SUNI_REGM_MCTRL_SDLE; + } + if (mode & UTP_LOOP_LINE) { + nmode &= ~UTP_LOOP_LINE; + if (val & (SUNI_REGM_MCTRL_LOOPT | SUNI_REGM_MCTRL_SDLE)) + return (EINVAL); + val |= SUNI_REGM_MCTRL_LLE; + } + if (mode & UTP_LOOP_PARAL) { + nmode &= ~UTP_LOOP_PARAL; + val |= SUNI_REGM_MCTRL_PDLE; + } + if (mode & UTP_LOOP_TWIST) { + nmode &= ~UTP_LOOP_TWIST; + val |= SUNI_REGM_MCTRL_TPLE; + } + if (nmode != 0) + return (EINVAL); + + err = UTP_WRITEREG(utp, SUNI_REGO_MCTRL, + SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_SDLE | SUNI_REGM_MCTRL_LOOPT | + SUNI_REGM_MCTRL_PDLE | SUNI_REGM_MCTRL_TPLE, val); + if (err) + return (err); + utp->loopback = mode; + + return (0); +} + +const struct utopia_chip utopia_chip_ultra = { + UTP_TYPE_SUNI_ULTRA, + "Suni/Ultra (PMC-5350)", + 256, + suni_reset_default, + suni_set_sdh, + suni_set_unass, + suni_set_noscramb, + suni_update_carrier, + suni_set_loopback_ultra, + suni_intr_default, + suni_lite_update_stats, +}; + +/* + * Set loopback mode for the 622 + */ +static int +suni_set_loopback_622(struct utopia *utp, u_int mode) +{ + int err; + uint32_t val; + uint8_t config; + int smode; + u_int nmode; + u_int n = 1; + + val = 0; + nmode = mode; + if (mode & UTP_LOOP_PATH) { + nmode &= ~UTP_LOOP_PATH; + val |= SUNI_REGM_MCTRLM_DPLE; + } + + err = UTP_READREGS(utp, SUNI_REGO_MCONFIG, &config, &n); + if (err != 0) + return (err); + smode = ((config & SUNI_REGM_MCONFIG_TMODE_622) == + SUNI_REGM_MCONFIG_TMODE_STS1_BIT && + (config & SUNI_REGM_MCONFIG_RMODE_622) == + SUNI_REGM_MCONFIG_RMODE_STS1_BIT); + + if (mode & UTP_LOOP_TIME) { + if (!smode) + return (EINVAL); + nmode &= ~UTP_LOOP_TIME; + val |= SUNI_REGM_MCTRLM_LOOPT; + } + if (mode & UTP_LOOP_DIAG) { + nmode &= ~UTP_LOOP_DIAG; + if (val & SUNI_REGM_MCTRLM_LOOPT) + return (EINVAL); + val |= SUNI_REGM_MCTRLM_DLE; + } + if (mode & UTP_LOOP_LINE) { + nmode &= ~UTP_LOOP_LINE; + if (val & (SUNI_REGM_MCTRLM_LOOPT | SUNI_REGM_MCTRLM_DLE)) + return (EINVAL); + val |= SUNI_REGM_MCTRLM_LLE; + } + if (nmode != 0) + return (EINVAL); + + err = UTP_WRITEREG(utp, SUNI_REGO_MCTRLM, + SUNI_REGM_MCTRLM_LLE | SUNI_REGM_MCTRLM_DLE | + SUNI_REGM_MCTRLM_DPLE | SUNI_REGM_MCTRL_LOOPT, val); + if (err) + return (err); + utp->loopback = mode; + + return (0); +} + +/* + * Reset the SUNI chip to reflect the current state of utopia. + */ +static int +suni_reset_622(struct utopia *utp) +{ + int err = 0; + + if (!(utp->flags & UTP_FL_NORESET)) { + err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, + SUNI_REGM_MRESET_RESET, SUNI_REGM_MRESET_RESET); + err |= UTP_WRITEREG(utp, SUNI_REGO_MRESET, + SUNI_REGM_MRESET_RESET, 0); + } + + /* disable test mode */ + err |= UTP_WRITEREG(utp, SUNI_REGO_MTEST, 0xff, + SUNI_REGM_MTEST_DS27_53_622); + + err |= suni_set_chip(utp); + + return (err ? EIO : 0); +} + +/* + * Update statistics from a SUNI/622 + */ +static void +suni_622_update_stats(struct utopia *utp) +{ + int err; + + /* write to the master if we can */ + if (!(utp->flags & UTP_FL_NORESET)) { + err = UTP_WRITEREG(utp, SUNI_REGO_MRESET, 0, 0); + } else { + err = UTP_WRITEREG(utp, SUNI_REGO_RSOP_BIP8, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_RLOPBIP8_24, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_RPOPBIP8, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_RACPCHCS, 0, 0); + err |= UTP_WRITEREG(utp, SUNI_REGO_TACPCNT, 0, 0); + } + if (err) { +#ifdef DIAGNOSTIC + printf("%s: register write error %s: %d\n", __func__, + utp->chip->name, err); +#endif + return; + } + + DELAY(8); + + utp->stats.rx_sbip += utopia_update(utp, + SUNI_REGO_RSOP_BIP8, 2, 0xffff); + utp->stats.rx_lbip += utopia_update(utp, + SUNI_REGO_RLOPBIP8_24, 3, 0xfffff); + utp->stats.rx_lfebe += utopia_update(utp, + SUNI_REGO_RLOPFEBE, 3, 0xfffff); + utp->stats.rx_pbip += utopia_update(utp, + SUNI_REGO_RPOPBIP8, 2, 0xffff); + utp->stats.rx_pfebe += utopia_update(utp, + SUNI_REGO_RPOPFEBE, 2, 0xffff); + utp->stats.rx_corr += utopia_update(utp, + SUNI_REGO_RACPCHCS_622, 2, 0xfff); + utp->stats.rx_uncorr += utopia_update(utp, + SUNI_REGO_RACPUHCS_622, 2, 0xfff); + utp->stats.rx_cells += utopia_update(utp, + SUNI_REGO_RACPCNT_622, 3, 0x1fffff); + utp->stats.tx_cells += utopia_update(utp, + SUNI_REGO_TACPCNT, 3, 0x1fffff); +} + +const struct utopia_chip utopia_chip_622 = { + UTP_TYPE_SUNI_622, + "Suni/622 (PMC-5355)", + 256, + suni_reset_622, + suni_set_sdh, + suni_set_unass, + suni_set_noscramb, + suni_update_carrier, + suni_set_loopback_622, + suni_intr_default, + suni_622_update_stats, +}; diff --git a/sys/dev/utopia/utopia.c b/sys/dev/utopia/utopia.c index e4a7c01b358f..1a9f353795bb 100644 --- a/sys/dev/utopia/utopia.c +++ b/sys/dev/utopia/utopia.c @@ -3,6 +3,8 @@ * Fraunhofer Institute for Open Communication Systems (FhG Fokus). * All rights reserved. * + * Author: Hartmut Brandt + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -23,8 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * Author: Hartmut Brandt */ #include @@ -52,11 +52,14 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include -#define READREGS(UTOPIA, REG, VALP, NP) \ - (UTOPIA)->methods->readregs((UTOPIA)->ifatm, REG, VALP, NP) -#define WRITEREG(UTOPIA, REG, MASK, VAL) \ - (UTOPIA)->methods->writereg((UTOPIA)->ifatm, REG, MASK, VAL) +/* known chips */ +extern const struct utopia_chip utopia_chip_idt77155; +extern const struct utopia_chip utopia_chip_idt77105; +extern const struct utopia_chip utopia_chip_lite; +extern const struct utopia_chip utopia_chip_ultra; +extern const struct utopia_chip utopia_chip_622; /* * Global list of all registered interfaces @@ -78,10 +81,10 @@ static struct proc *utopia_kproc; static void utopia_dump(struct utopia *) __unused; /* - * Statistics update inlines + * Read a multi-register value. */ -static uint32_t -utp_update(struct utopia *utp, u_int reg, u_int nreg, uint32_t mask) +uint32_t +utopia_update(struct utopia *utp, u_int reg, u_int nreg, uint32_t mask) { int err; u_int n; @@ -89,7 +92,7 @@ utp_update(struct utopia *utp, u_int reg, u_int nreg, uint32_t mask) uint32_t val; n = nreg; - if ((err = READREGS(utp, reg, regs, &n)) != 0) { + if ((err = UTP_READREGS(utp, reg, regs, &n)) != 0) { #ifdef DIAGNOSTIC printf("%s: register read error %s(%u,%u): %d\n", __func__, utp->chip->name, reg, nreg, err); @@ -111,13 +114,6 @@ utp_update(struct utopia *utp, u_int reg, u_int nreg, uint32_t mask) return (val & mask); } -#define UPDATE8(UTP, REG) utp_update(UTP, REG, 1, 0xff) -#define UPDATE12(UTP, REG) utp_update(UTP, REG, 2, 0xfff) -#define UPDATE16(UTP, REG) utp_update(UTP, REG, 2, 0xffff) -#define UPDATE19(UTP, REG) utp_update(UTP, REG, 3, 0x7ffff) -#define UPDATE20(UTP, REG) utp_update(UTP, REG, 3, 0xfffff) -#define UPDATE21(UTP, REG) utp_update(UTP, REG, 3, 0x1fffff) - /* * Debugging - dump all registers. */ @@ -128,8 +124,8 @@ utopia_dump(struct utopia *utp) u_int n = 256, i; int err; - if ((err = READREGS(utp, SUNI_REGO_MRESET, regs, &n)) != 0) { - printf("SUNI read error %d\n", err); + if ((err = UTP_READREGS(utp, 0, regs, &n)) != 0) { + printf("UTOPIA reg read error %d\n", err); return; } for (i = 0; i < n; i++) { @@ -148,7 +144,7 @@ utopia_dump(struct utopia *utp) /* * Update the carrier status */ -static void +void utopia_check_carrier(struct utopia *utp, u_int carr_ok) { int old; @@ -171,902 +167,13 @@ utopia_check_carrier(struct utopia *utp, u_int carr_ok) } } -static int -utopia_update_carrier_default(struct utopia *utp) -{ - int err; - uint8_t reg; - u_int n = 1; - - if ((err = READREGS(utp, SUNI_REGO_RSOPSIS, ®, &n)) != 0) { - utp->carrier = UTP_CARR_UNKNOWN; - return (err); - } - utopia_check_carrier(utp, !(reg & SUNI_REGM_RSOPSIS_LOSV)); - return (0); -} - -/* - * enable/disable scrambling - */ -static int -utopia_set_noscramb_default(struct utopia *utp, int noscramb) -{ - int err; - - if (noscramb) { - err = WRITEREG(utp, SUNI_REGO_TACPCTRL, - SUNI_REGM_TACPCTRL_DSCR, SUNI_REGM_TACPCTRL_DSCR); - if (err) - return (err); - err = WRITEREG(utp, SUNI_REGO_RACPCTRL, - SUNI_REGM_RACPCTRL_DDSCR, SUNI_REGM_RACPCTRL_DDSCR); - if (err) - return (err); - utp->state |= UTP_ST_NOSCRAMB; - } else { - err = WRITEREG(utp, SUNI_REGO_TACPCTRL, - SUNI_REGM_TACPCTRL_DSCR, 0); - if (err) - return (err); - err = WRITEREG(utp, SUNI_REGO_RACPCTRL, - SUNI_REGM_RACPCTRL_DDSCR, 0); - if (err) - return (err); - utp->state &= ~UTP_ST_NOSCRAMB; - } - return (0); -} - -/* - * set SONET/SDH mode - */ -static int -utopia_set_sdh_default(struct utopia *utp, int sdh) -{ - int err; - - if (sdh) - err = WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1, - SUNI_REGM_TPOPAPTR_S, - SUNI_REGM_SDH << SUNI_REGS_TPOPAPTR_S); - else - err = WRITEREG(utp, SUNI_REGO_TPOPAPTR + 1, - SUNI_REGM_TPOPAPTR_S, - SUNI_REGM_SONET << SUNI_REGS_TPOPAPTR_S); - if (err != 0) - return (err); - - utp->state &= ~UTP_ST_SDH; - if (sdh) - utp->state |= UTP_ST_SDH; - - return (0); -} - -/* - * set idle/unassigned cells - */ -static int -utopia_set_unass_default(struct utopia *utp, int unass) -{ - int err; - - if (unass) - err = WRITEREG(utp, SUNI_REGO_TACPIDLEH, - 0xff, (0 << SUNI_REGS_TACPIDLEH_CLP)); - else - err = WRITEREG(utp, SUNI_REGO_TACPIDLEH, - 0xff, (1 << SUNI_REGS_TACPIDLEH_CLP)); - if (err != 0) - return (err); - - utp->state &= ~UTP_ST_UNASS; - if (unass) - utp->state |= UTP_ST_UNASS; - - return (0); -} - -/* - * Set loopback mode for the Lite - */ -static int -utopia_set_loopback_lite(struct utopia *utp, u_int mode) -{ - int err; - uint32_t val; - u_int nmode; - - val = 0; - nmode = mode; - if (mode & UTP_LOOP_TIME) { - nmode &= ~UTP_LOOP_TIME; - val |= SUNI_REGM_MCTRL_LOOPT; - } - if (mode & UTP_LOOP_DIAG) { - nmode &= ~UTP_LOOP_DIAG; - val |= SUNI_REGM_MCTRL_DLE; - } - if (mode & UTP_LOOP_LINE) { - nmode &= ~UTP_LOOP_LINE; - if (val & SUNI_REGM_MCTRL_DLE) - return (EINVAL); - val |= SUNI_REGM_MCTRL_LLE; - } - if (nmode != 0) - return (EINVAL); - - err = WRITEREG(utp, SUNI_REGO_MCTRL, - SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_DLE | SUNI_REGM_MCTRL_LOOPT, - val); - if (err) - return (err); - utp->loopback = mode; - - return (0); -} - -/* - * Set loopback mode for the Ultra - */ -static int -utopia_set_loopback_ultra(struct utopia *utp, u_int mode) -{ - int err; - uint32_t val; - u_int nmode; - - val = 0; - nmode = mode; - if (mode & UTP_LOOP_TIME) { - nmode &= ~UTP_LOOP_TIME; - val |= SUNI_REGM_MCTRL_LOOPT; - } - if (mode & UTP_LOOP_DIAG) { - nmode &= ~UTP_LOOP_DIAG; - if (val & SUNI_REGM_MCTRL_LOOPT) - return (EINVAL); - val |= SUNI_REGM_MCTRL_SDLE; - } - if (mode & UTP_LOOP_LINE) { - nmode &= ~UTP_LOOP_LINE; - if (val & (SUNI_REGM_MCTRL_LOOPT | SUNI_REGM_MCTRL_SDLE)) - return (EINVAL); - val |= SUNI_REGM_MCTRL_LLE; - } - if (mode & UTP_LOOP_PARAL) { - nmode &= ~UTP_LOOP_PARAL; - val |= SUNI_REGM_MCTRL_PDLE; - } - if (mode & UTP_LOOP_TWIST) { - nmode &= ~UTP_LOOP_TWIST; - val |= SUNI_REGM_MCTRL_TPLE; - } - if (nmode != 0) - return (EINVAL); - - err = WRITEREG(utp, SUNI_REGO_MCTRL, - SUNI_REGM_MCTRL_LLE | SUNI_REGM_MCTRL_SDLE | SUNI_REGM_MCTRL_LOOPT | - SUNI_REGM_MCTRL_PDLE | SUNI_REGM_MCTRL_TPLE, val); - if (err) - return (err); - utp->loopback = mode; - - return (0); -} - -/* - * Set loopback mode for the Ultra - */ -static int -utopia_set_loopback_622(struct utopia *utp, u_int mode) -{ - int err; - uint32_t val; - uint8_t config; - int smode; - u_int nmode; - u_int n = 1; - - val = 0; - nmode = mode; - if (mode & UTP_LOOP_PATH) { - nmode &= ~UTP_LOOP_PATH; - val |= SUNI_REGM_MCTRLM_DPLE; - } - - err = READREGS(utp, SUNI_REGO_MCONFIG, &config, &n); - if (err != 0) - return (err); - smode = ((config & SUNI_REGM_MCONFIG_TMODE_622) == - SUNI_REGM_MCONFIG_TMODE_STS1_BIT && - (config & SUNI_REGM_MCONFIG_RMODE_622) == - SUNI_REGM_MCONFIG_RMODE_STS1_BIT); - - if (mode & UTP_LOOP_TIME) { - if (!smode) - return (EINVAL); - nmode &= ~UTP_LOOP_TIME; - val |= SUNI_REGM_MCTRLM_LOOPT; - } - if (mode & UTP_LOOP_DIAG) { - nmode &= ~UTP_LOOP_DIAG; - if (val & SUNI_REGM_MCTRLM_LOOPT) - return (EINVAL); - val |= SUNI_REGM_MCTRLM_DLE; - } - if (mode & UTP_LOOP_LINE) { - nmode &= ~UTP_LOOP_LINE; - if (val & (SUNI_REGM_MCTRLM_LOOPT | SUNI_REGM_MCTRLM_DLE)) - return (EINVAL); - val |= SUNI_REGM_MCTRLM_LLE; - } - if (nmode != 0) - return (EINVAL); - - err = WRITEREG(utp, SUNI_REGO_MCTRLM, - SUNI_REGM_MCTRLM_LLE | SUNI_REGM_MCTRLM_DLE | - SUNI_REGM_MCTRLM_DPLE | SUNI_REGM_MCTRL_LOOPT, val); - if (err) - return (err); - utp->loopback = mode; - - return (0); -} - -/* - * Set the SUNI chip to reflect the current state in utopia. - * Assume, that the chip has been reset. - */ -static int -utopia_set_chip(struct utopia *utp) -{ - int err = 0; - - /* set sonet/sdh */ - err |= utopia_set_sdh(utp, utp->state & UTP_ST_SDH); - - /* unassigned or idle cells */ - err |= utopia_set_unass(utp, utp->state & UTP_ST_UNASS); - err |= WRITEREG(utp, SUNI_REGO_TACPIDLEP, 0xff, 0x6a); - - /* loopback */ - err |= utopia_set_loopback(utp, utp->loopback); - - /* update carrier state */ - err |= utopia_update_carrier(utp); - - /* enable interrupts on LOS */ - err |= WRITEREG(utp, SUNI_REGO_RSOPCIE, - SUNI_REGM_RSOPCIE_LOSE, SUNI_REGM_RSOPCIE_LOSE); - - return (err ? EIO : 0); -} - -/* - * Reset the SUNI chip to reflect the current state of utopia. - */ -static int -utopia_reset_default(struct utopia *utp) -{ - int err = 0; - - if (!(utp->flags & UTP_FL_NORESET)) { - err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET, - SUNI_REGM_MRESET_RESET); - err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET, - 0); - } - - /* disable test mode */ - err |= WRITEREG(utp, SUNI_REGO_MTEST, 0xff, 0x00); - - err |= utopia_set_chip(utp); - - return (err ? EIO : 0); -} - -/* - * Reset the SUNI chip to reflect the current state of utopia. - */ -static int -utopia_reset_622(struct utopia *utp) -{ - int err = 0; - - if (!(utp->flags & UTP_FL_NORESET)) { - err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET, - SUNI_REGM_MRESET_RESET); - err |= WRITEREG(utp, SUNI_REGO_MRESET, SUNI_REGM_MRESET_RESET, - 0); - } - - /* disable test mode */ - err |= WRITEREG(utp, SUNI_REGO_MTEST, 0xff, - SUNI_REGM_MTEST_DS27_53_622); - - err |= utopia_set_chip(utp); - - return (err ? EIO : 0); -} - -/* - * Handle interrupt on lite chip - */ -static void -utopia_intr_default(struct utopia *utp) -{ - uint8_t regs[SUNI_REGO_MTEST]; - u_int n = SUNI_REGO_MTEST; - int err; - - /* Read all registers. This acks the interrupts */ - if ((err = READREGS(utp, SUNI_REGO_MRESET, regs, &n)) != 0) { - printf("SUNI read error %d\n", err); - return; - } - if (n <= SUNI_REGO_RSOPSIS) { - printf("%s: could not read RSOPSIS", __func__); - return; - } - /* check for LOSI (loss of signal) */ - if ((regs[SUNI_REGO_MISTATUS] & SUNI_REGM_MISTATUS_RSOPI) && - (regs[SUNI_REGO_RSOPSIS] & SUNI_REGM_RSOPSIS_LOSI)) - utopia_check_carrier(utp, !(regs[SUNI_REGO_RSOPSIS] - & SUNI_REGM_RSOPSIS_LOSV)); -} - -/* - * Update statistics from a SUNI/LITE or SUNI/ULTRA - */ -static void -suni_lite_update_stats(struct utopia *utp) -{ - int err; - - /* write to the master if we can */ - if (!(utp->flags & UTP_FL_NORESET)) { - err = WRITEREG(utp, SUNI_REGO_MRESET, 0, 0); - } else { - err = WRITEREG(utp, SUNI_REGO_RSOP_BIP8, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_RLOPBIP8_24, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_RPOPBIP8, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_RACPCHCS, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_TACPCNT, 0, 0); - - } - if (err) { -#ifdef DIAGNOSTIC - printf("%s: register write error %s: %d\n", __func__, - utp->chip->name, err); -#endif - return; - } - - DELAY(8); - - utp->stats.rx_sbip += UPDATE16(utp, SUNI_REGO_RSOP_BIP8); - utp->stats.rx_lbip += UPDATE20(utp, SUNI_REGO_RLOPBIP8_24); - utp->stats.rx_lfebe += UPDATE20(utp, SUNI_REGO_RLOPFEBE); - utp->stats.rx_pbip += UPDATE16(utp, SUNI_REGO_RPOPBIP8); - utp->stats.rx_pfebe += UPDATE16(utp, SUNI_REGO_RPOPFEBE); - utp->stats.rx_corr += UPDATE8(utp, SUNI_REGO_RACPCHCS); - utp->stats.rx_uncorr += UPDATE8(utp, SUNI_REGO_RACPUHCS); - utp->stats.rx_cells += UPDATE19(utp, SUNI_REGO_RACPCNT); - utp->stats.tx_cells += UPDATE19(utp, SUNI_REGO_TACPCNT); -} - -/* - * Update statistics from a SUNI/622 - */ -static void -suni_622_update_stats(struct utopia *utp) -{ - int err; - - /* write to the master if we can */ - if (!(utp->flags & UTP_FL_NORESET)) { - err = WRITEREG(utp, SUNI_REGO_MRESET, 0, 0); - } else { - err = WRITEREG(utp, SUNI_REGO_RSOP_BIP8, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_RLOPBIP8_24, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_RPOPBIP8, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_RACPCHCS, 0, 0); - err |= WRITEREG(utp, SUNI_REGO_TACPCNT, 0, 0); - } - if (err) { -#ifdef DIAGNOSTIC - printf("%s: register write error %s: %d\n", __func__, - utp->chip->name, err); -#endif - return; - } - - DELAY(8); - - utp->stats.rx_sbip += UPDATE16(utp, SUNI_REGO_RSOP_BIP8); - utp->stats.rx_lbip += UPDATE20(utp, SUNI_REGO_RLOPBIP8_24); - utp->stats.rx_lfebe += UPDATE20(utp, SUNI_REGO_RLOPFEBE); - utp->stats.rx_pbip += UPDATE16(utp, SUNI_REGO_RPOPBIP8); - utp->stats.rx_pfebe += UPDATE16(utp, SUNI_REGO_RPOPFEBE); - utp->stats.rx_corr += UPDATE12(utp, SUNI_REGO_RACPCHCS_622); - utp->stats.rx_uncorr += UPDATE12(utp, SUNI_REGO_RACPUHCS_622); - utp->stats.rx_cells += UPDATE21(utp, SUNI_REGO_RACPCNT_622); - utp->stats.tx_cells += UPDATE21(utp, SUNI_REGO_TACPCNT); -} - -static const struct utopia_chip chip_622 = { - UTP_TYPE_SUNI_622, - "Suni/622 (PMC-5355)", - 256, - utopia_reset_622, - utopia_set_sdh_default, - utopia_set_unass_default, - utopia_set_noscramb_default, - utopia_update_carrier_default, - utopia_set_loopback_622, - utopia_intr_default, - suni_622_update_stats, -}; -static const struct utopia_chip chip_lite = { - UTP_TYPE_SUNI_LITE, - "Suni/Lite (PMC-5346)", - 256, - utopia_reset_default, - utopia_set_sdh_default, - utopia_set_unass_default, - utopia_set_noscramb_default, - utopia_update_carrier_default, - utopia_set_loopback_lite, - utopia_intr_default, - suni_lite_update_stats, -}; -static const struct utopia_chip chip_ultra = { - UTP_TYPE_SUNI_ULTRA, - "Suni/Ultra (PMC-5350)", - 256, - utopia_reset_default, - utopia_set_sdh_default, - utopia_set_unass_default, - utopia_set_noscramb_default, - utopia_update_carrier_default, - utopia_set_loopback_ultra, - utopia_intr_default, - suni_lite_update_stats, -}; - -/* - * Reset IDT77105. There is really no way to reset this thing by acessing - * the registers. Load the registers with default values. - */ -static int -idt77105_reset(struct utopia *utp) -{ - int err = 0; - u_int n; - uint8_t val[2]; - - err |= WRITEREG(utp, IDTPHY_REGO_MCR, 0xff, - IDTPHY_REGM_MCR_DRIC | IDTPHY_REGM_MCR_EI); - n = 1; - err |= READREGS(utp, IDTPHY_REGO_ISTAT, val, &n); - err |= WRITEREG(utp, IDTPHY_REGO_DIAG, 0xff, 0); - err |= WRITEREG(utp, IDTPHY_REGO_LHEC, 0xff, 0); - - err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_SEC); - n = 2; - err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n); - - err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_TX); - n = 2; - err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n); - - err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_RX); - n = 2; - err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n); - - err |= WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, IDTPHY_REGM_CNTS_HECE); - n = 2; - err |= READREGS(utp, IDTPHY_REGO_CNT, val, &n); - - err |= WRITEREG(utp, IDTPHY_REGO_MCR, IDTPHY_REGM_MCR_DREC, - IDTPHY_REGM_MCR_DREC); - err |= WRITEREG(utp, IDTPHY_REGO_DIAG, IDTPHY_REGM_DIAG_RFLUSH, - IDTPHY_REGM_DIAG_RFLUSH); - - /* loopback */ - err |= utopia_set_loopback(utp, utp->loopback); - - /* update carrier state */ - err |= utopia_update_carrier(utp); - - return (err ? EIO : 0); -} - static int unknown_inval(struct utopia *utp, int what __unused) { + return (EINVAL); } -static int -idt77105_update_carrier(struct utopia *utp) -{ - int err; - uint8_t reg; - u_int n = 1; - - if ((err = READREGS(utp, IDTPHY_REGO_ISTAT, ®, &n)) != 0) { - utp->carrier = UTP_CARR_UNKNOWN; - return (err); - } - utopia_check_carrier(utp, reg & IDTPHY_REGM_ISTAT_GOOD); - return (0); -} - -static int -idt77105_set_loopback(struct utopia *utp, u_int mode) -{ - int err; - - switch (mode) { - case UTP_LOOP_NONE: - err = WRITEREG(utp, IDTPHY_REGO_DIAG, - IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_NONE); - break; - - case UTP_LOOP_DIAG: - err = WRITEREG(utp, IDTPHY_REGO_DIAG, - IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_PHY); - break; - - case UTP_LOOP_LINE: - err = WRITEREG(utp, IDTPHY_REGO_DIAG, - IDTPHY_REGM_DIAG_LOOP, IDTPHY_REGM_DIAG_LOOP_LINE); - break; - - default: - return (EINVAL); - } - if (err) - return (err); - utp->loopback = mode; - return (0); -} - -/* - * Handle interrupt on IDT77105 chip - */ -static void -idt77105_intr(struct utopia *utp) -{ - uint8_t reg; - u_int n = 1; - int err; - - /* Interrupt status and ack the interrupt */ - if ((err = READREGS(utp, IDTPHY_REGO_ISTAT, ®, &n)) != 0) { - printf("IDT77105 read error %d\n", err); - return; - } - /* check for signal condition */ - utopia_check_carrier(utp, reg & IDTPHY_REGM_ISTAT_GOOD); -} - -static void -idt77105_update_stats(struct utopia *utp) -{ - int err = 0; - uint8_t regs[2]; - u_int n; - -#ifdef DIAGNOSTIC -#define UDIAG(F,A,B) printf(F, A, B) -#else -#define UDIAG(F,A,B) do { } while (0) -#endif - -#define UPD(FIELD, CODE, N, MASK) \ - err = WRITEREG(utp, IDTPHY_REGO_CNTS, 0xff, CODE); \ - if (err != 0) { \ - UDIAG("%s: cannot write CNTS: %d\n", __func__, err); \ - return; \ - } \ - n = N; \ - err = READREGS(utp, IDTPHY_REGO_CNT, regs, &n); \ - if (err != 0) { \ - UDIAG("%s: cannot read CNT: %d\n", __func__, err); \ - return; \ - } \ - if (n != N) { \ - UDIAG("%s: got only %u registers\n", __func__, n); \ - return; \ - } \ - if (N == 1) \ - utp->stats.FIELD += (regs[0] & MASK); \ - else \ - utp->stats.FIELD += (regs[0] | (regs[1] << 8)) & MASK; - - UPD(rx_symerr, IDTPHY_REGM_CNTS_SEC, 1, 0xff); - UPD(tx_cells, IDTPHY_REGM_CNTS_TX, 2, 0xffff); - UPD(rx_cells, IDTPHY_REGM_CNTS_RX, 2, 0xffff); - UPD(rx_uncorr, IDTPHY_REGM_CNTS_HECE, 1, 0x1f); - -#undef UDIAG -#undef UPD -} - -static const struct utopia_chip chip_idt77105 = { - UTP_TYPE_IDT77105, - "IDT77105", - 7, - idt77105_reset, - unknown_inval, - unknown_inval, - unknown_inval, - idt77105_update_carrier, - idt77105_set_loopback, - idt77105_intr, - idt77105_update_stats, -}; - -/* - * Update the carrier status - */ -static int -idt77155_update_carrier(struct utopia *utp) -{ - int err; - uint8_t reg; - u_int n = 1; - - if ((err = READREGS(utp, IDTPHY_REGO_RSOS, ®, &n)) != 0) { - utp->carrier = UTP_CARR_UNKNOWN; - return (err); - } - utopia_check_carrier(utp, !(reg & IDTPHY_REGM_RSOS_LOS)); - return (0); -} - -/* - * Handle interrupt on IDT77155 chip - */ -static void -idt77155_intr(struct utopia *utp) -{ - uint8_t reg; - u_int n = 1; - int err; - - if ((err = READREGS(utp, IDTPHY_REGO_RSOS, ®, &n)) != 0) { - printf("IDT77105 read error %d\n", err); - return; - } - utopia_check_carrier(utp, !(reg & IDTPHY_REGM_RSOS_LOS)); -} - -/* - * set SONET/SDH mode - */ -static int -idt77155_set_sdh(struct utopia *utp, int sdh) -{ - int err; - - if (sdh) - err = WRITEREG(utp, IDTPHY_REGO_PTRM, - IDTPHY_REGM_PTRM_SS, IDTPHY_REGM_PTRM_SDH); - else - err = WRITEREG(utp, IDTPHY_REGO_PTRM, - IDTPHY_REGM_PTRM_SS, IDTPHY_REGM_PTRM_SONET); - if (err != 0) - return (err); - - utp->state &= ~UTP_ST_SDH; - if (sdh) - utp->state |= UTP_ST_SDH; - - return (0); -} - -/* - * set idle/unassigned cells - */ -static int -idt77155_set_unass(struct utopia *utp, int unass) -{ - int err; - - if (unass) - err = WRITEREG(utp, IDTPHY_REGO_TCHP, 0xff, 0); - else - err = WRITEREG(utp, IDTPHY_REGO_TCHP, 0xff, 1); - if (err != 0) - return (err); - - utp->state &= ~UTP_ST_UNASS; - if (unass) - utp->state |= UTP_ST_UNASS; - - return (0); -} - -/* - * enable/disable scrambling - */ -static int -idt77155_set_noscramb(struct utopia *utp, int noscramb) -{ - int err; - - if (noscramb) { - err = WRITEREG(utp, IDTPHY_REGO_TCC, - IDTPHY_REGM_TCC_DSCR, IDTPHY_REGM_TCC_DSCR); - if (err) - return (err); - err = WRITEREG(utp, IDTPHY_REGO_RCC, - IDTPHY_REGM_RCC_DSCR, IDTPHY_REGM_RCC_DSCR); - if (err) - return (err); - utp->state |= UTP_ST_NOSCRAMB; - } else { - err = WRITEREG(utp, IDTPHY_REGO_TCC, - IDTPHY_REGM_TCC_DSCR, 0); - if (err) - return (err); - err = WRITEREG(utp, IDTPHY_REGO_RCC, - IDTPHY_REGM_RCC_DSCR, 0); - if (err) - return (err); - utp->state &= ~UTP_ST_NOSCRAMB; - } - return (0); -} - -/* - * Set loopback mode for the 77155 - */ -static int -idt77155_set_loopback(struct utopia *utp, u_int mode) -{ - int err; - uint32_t val; - u_int nmode; - - val = 0; - nmode = mode; - if (mode & UTP_LOOP_TIME) { - nmode &= ~UTP_LOOP_TIME; - val |= IDTPHY_REGM_MCTL_TLOOP; - } - if (mode & UTP_LOOP_DIAG) { - nmode &= ~UTP_LOOP_DIAG; - val |= IDTPHY_REGM_MCTL_DLOOP; - } - if (mode & UTP_LOOP_LINE) { - nmode &= ~UTP_LOOP_LINE; - val |= IDTPHY_REGM_MCTL_LLOOP; - } - if (nmode != 0) - return (EINVAL); - - err = WRITEREG(utp, IDTPHY_REGO_MCTL, IDTPHY_REGM_MCTL_TLOOP | - IDTPHY_REGM_MCTL_DLOOP | IDTPHY_REGM_MCTL_LLOOP, val); - if (err) - return (err); - utp->loopback = mode; - - return (0); -} - -/* - * Set the chip to reflect the current state in utopia. - * Assume, that the chip has been reset. - */ -static int -idt77155_set_chip(struct utopia *utp) -{ - int err = 0; - - /* set sonet/sdh */ - err |= idt77155_set_sdh(utp, utp->state & UTP_ST_SDH); - - /* unassigned or idle cells */ - err |= idt77155_set_unass(utp, utp->state & UTP_ST_UNASS); - - /* loopback */ - err |= idt77155_set_loopback(utp, utp->loopback); - - /* update carrier state */ - err |= idt77155_update_carrier(utp); - - /* enable interrupts on LOS */ - err |= WRITEREG(utp, IDTPHY_REGO_INT, - IDTPHY_REGM_INT_RXSOHI, IDTPHY_REGM_INT_RXSOHI); - err |= WRITEREG(utp, IDTPHY_REGO_RSOC, - IDTPHY_REGM_RSOC_LOSI, IDTPHY_REGM_RSOC_LOSI); - - return (err ? EIO : 0); -} - -/* - * Reset the chip to reflect the current state of utopia. - */ -static int -idt77155_reset(struct utopia *utp) -{ - int err = 0; - - if (!(utp->flags & UTP_FL_NORESET)) { - err |= WRITEREG(utp, IDTPHY_REGO_MRID, IDTPHY_REGM_MRID_RESET, - IDTPHY_REGM_MRID_RESET); - err |= WRITEREG(utp, IDTPHY_REGO_MRID, IDTPHY_REGM_MRID_RESET, - 0); - } - - err |= idt77155_set_chip(utp); - - return (err ? EIO : 0); -} - -/* - * Update statistics from a IDT77155 - * This appears to be the same as for the Suni/Lite and Ultra. IDT however - * makes no assessment about the transfer time. Assume 7us. - */ -static void -idt77155_update_stats(struct utopia *utp) -{ - int err; - - /* write to the master if we can */ - if (!(utp->flags & UTP_FL_NORESET)) { - err = WRITEREG(utp, IDTPHY_REGO_MRID, 0, 0); - } else { - err = WRITEREG(utp, IDTPHY_REGO_BIPC, 0, 0); - err |= WRITEREG(utp, IDTPHY_REGO_B2EC, 0, 0); - err |= WRITEREG(utp, IDTPHY_REGO_B3EC, 0, 0); - err |= WRITEREG(utp, IDTPHY_REGO_CEC, 0, 0); - err |= WRITEREG(utp, IDTPHY_REGO_TXCNT, 0, 0); - - } - if (err) { -#ifdef DIAGNOSTIC - printf("%s: register write error %s: %d\n", __func__, - utp->chip->name, err); -#endif - return; - } - - DELAY(8); - - utp->stats.rx_sbip += UPDATE16(utp, IDTPHY_REGO_BIPC); - utp->stats.rx_lbip += UPDATE20(utp, IDTPHY_REGO_B2EC); - utp->stats.rx_lfebe += UPDATE20(utp, IDTPHY_REGO_FEBEC); - utp->stats.rx_pbip += UPDATE16(utp, IDTPHY_REGO_B3EC); - utp->stats.rx_pfebe += UPDATE16(utp, IDTPHY_REGO_PFEBEC); - utp->stats.rx_corr += UPDATE8(utp, IDTPHY_REGO_CEC); - utp->stats.rx_uncorr += UPDATE8(utp, IDTPHY_REGO_UEC); - utp->stats.rx_cells += UPDATE19(utp, IDTPHY_REGO_RCCNT); - utp->stats.tx_cells += UPDATE19(utp, IDTPHY_REGO_TXCNT); -} - - -static const struct utopia_chip chip_idt77155 = { - UTP_TYPE_IDT77155, - "IDT77155", - 0x80, - idt77155_reset, - idt77155_set_sdh, - idt77155_set_unass, - idt77155_set_noscramb, - idt77155_update_carrier, - idt77155_set_loopback, - idt77155_intr, - idt77155_update_stats, -}; - static int unknown_reset(struct utopia *utp __unused) { @@ -1096,7 +203,7 @@ unknown_update_stats(struct utopia *utp __unused) { } -static const struct utopia_chip chip_unknown = { +static const struct utopia_chip utopia_chip_unknown = { UTP_TYPE_UNKNOWN, "unknown", 0, @@ -1227,39 +334,42 @@ utopia_start(struct utopia *utp) int err; u_int n = 1; - if ((err = READREGS(utp, SUNI_REGO_MRESET, ®, &n)) != 0) + /* + * Try to find out what chip we have + */ + if ((err = UTP_READREGS(utp, SUNI_REGO_MRESET, ®, &n)) != 0) return (err); switch (reg & SUNI_REGM_MRESET_TYPE) { case SUNI_REGM_MRESET_TYPE_622: - utp->chip = &chip_622; + utp->chip = &utopia_chip_622; break; case SUNI_REGM_MRESET_TYPE_LITE: /* this may be either a SUNI LITE or a IDT77155 * * Read register 0x70. The SUNI doesn't have it */ n = 1; - if ((err = READREGS(utp, IDTPHY_REGO_RBER, ®, &n)) != 0) + if ((err = UTP_READREGS(utp, IDTPHY_REGO_RBER, ®, &n)) != 0) return (err); if ((reg & ~IDTPHY_REGM_RBER_RESV) == (IDTPHY_REGM_RBER_FAIL | IDTPHY_REGM_RBER_WARN)) - utp->chip = &chip_idt77155; + utp->chip = &utopia_chip_idt77155; else - utp->chip = &chip_lite; + utp->chip = &utopia_chip_lite; break; case SUNI_REGM_MRESET_TYPE_ULTRA: - utp->chip = &chip_ultra; + utp->chip = &utopia_chip_ultra; break; default: if (reg == (IDTPHY_REGM_MCR_DRIC | IDTPHY_REGM_MCR_EI)) - utp->chip = &chip_idt77105; + utp->chip = &utopia_chip_idt77105; else { if_printf(&utp->ifatm->ifnet, "unknown ATM-PHY chip %#x\n", reg); - utp->chip = &chip_unknown; + utp->chip = &utopia_chip_unknown; } break; } @@ -1293,7 +403,7 @@ utopia_sysctl_regs(SYSCTL_HANDLER_ARGS) val = malloc(sizeof(uint8_t) * n, M_TEMP, M_WAITOK); UTP_LOCK(utp); - error = READREGS(utp, 0, val, &n); + error = UTP_READREGS(utp, 0, val, &n); UTP_UNLOCK(utp); if (error) { @@ -1311,7 +421,7 @@ utopia_sysctl_regs(SYSCTL_HANDLER_ARGS) return (error); UTP_LOCK(utp); - error = WRITEREG(utp, new[0], new[1], new[2]); + error = UTP_WRITEREG(utp, new[0], new[1], new[2]); UTP_UNLOCK(utp); return (error); @@ -1406,7 +516,7 @@ utopia_attach(struct utopia *utp, struct ifatm *ifatm, struct ifmedia *media, utp->methods = m; utp->media = media; utp->lock = lock; - utp->chip = &chip_unknown; + utp->chip = &utopia_chip_unknown; utp->stats.version = 1; ifmedia_init(media, diff --git a/sys/dev/utopia/utopia.h b/sys/dev/utopia/utopia.h index 0c95aa344d4f..6e42e99b2e51 100644 --- a/sys/dev/utopia/utopia.h +++ b/sys/dev/utopia/utopia.h @@ -50,9 +50,10 @@ struct utopia_print { #define UTP_REGT_INT19 0x5 /* 19 bit LE hex */ #define UTP_REGT_INT20 0x6 /* 20 bit LE hex */ #define UTP_REGT_INT21 0x7 /* 21 bit LE hex */ +#define UTP_REGT_INT18 0x8 /* 18 bit LE hex */ /* number of additional registers per type */ -#define UTP_REG_ADD 0, 0, 1, 1, 1, 2, 2, 2 +#define UTP_REG_ADD 0, 0, 1, 1, 1, 2, 2, 2, 2 /* flags field */ #define UTP_FL_NORESET 0x0001 /* cannot write MRESET register */ @@ -87,6 +88,7 @@ struct utopia_print { #define UTP_TYPE_SUNI_622 3 #define UTP_TYPE_IDT77105 4 #define UTP_TYPE_IDT77155 5 +#define UTP_TYPE_CX28250 6 /* * Statistics. These structures are versioned. diff --git a/sys/dev/utopia/utopia_priv.h b/sys/dev/utopia/utopia_priv.h new file mode 100644 index 000000000000..cbb242cb9991 --- /dev/null +++ b/sys/dev/utopia/utopia_priv.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2005 + * Hartmut Brandt. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Hartmut Brandt + * + * $FreeBSD$ + * + * Private include file for the interface between chip files and + * the utopia main stuff. + */ + +#ifndef _DEV_UTOPIA_UTOPIA_PRIV_H +#define _DEV_UTOPIA_UTOPIA_PRIV_H + +#define UTP_READREGS(UTOPIA, REG, VALP, NP) \ + (UTOPIA)->methods->readregs((UTOPIA)->ifatm, REG, VALP, NP) +#define UTP_WRITEREG(UTOPIA, REG, MASK, VAL) \ + (UTOPIA)->methods->writereg((UTOPIA)->ifatm, REG, MASK, VAL) + +uint32_t utopia_update(struct utopia *, u_int, u_int, uint32_t); +void utopia_check_carrier(struct utopia *, u_int); + +#endif /* _DEV_UTOPIA_UTOPIA_PRIV_H */