1150957Simp/*- 2150957Simp * Copyright (c) 2003, David Madole 3150957Simp * All rights reserved. 4150957Simp * Copyright (c) 2005, M. Warner Losh. 5150957Simp * All rights reserved. 6150957Simp * 7150957Simp * Redistribution and use in source and binary forms, with or without 8150957Simp * modification, are permitted provided that the following conditions 9150957Simp * are met: 10150957Simp * 1. Redistributions of source code must retain the above copyright 11150957Simp * notice unmodified, this list of conditions, and the following 12150957Simp * disclaimer. 13150957Simp * 2. Redistributions in binary form must reproduce the above copyright 14150957Simp * notice, this list of conditions and the following disclaimer in the 15150957Simp * documentation and/or other materials provided with the distribution. 16150957Simp * 17150957Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18150957Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19150957Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20150957Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21150957Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22150957Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23150957Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24150957Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25150957Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26150957Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27150957Simp * SUCH DAMAGE. 28150957Simp * 29150957Simp * Based on patches subitted by: David Madole, edited by M. Warner Losh. 30150957Simp */ 31150957Simp 32150957Simp 33150957Simp#include <sys/cdefs.h> 34150957Simp__FBSDID("$FreeBSD$"); 35150957Simp 36150957Simp#include "opt_ed.h" 37150957Simp 38150957Simp#include <sys/param.h> 39150957Simp#include <sys/systm.h> 40150957Simp#include <sys/sockio.h> 41150957Simp#include <sys/mbuf.h> 42150957Simp#include <sys/kernel.h> 43150957Simp#include <sys/socket.h> 44150957Simp#include <sys/syslog.h> 45150957Simp 46150957Simp#include <sys/bus.h> 47150957Simp 48150957Simp#include <machine/bus.h> 49150957Simp#include <sys/rman.h> 50150957Simp#include <machine/resource.h> 51150957Simp 52150957Simp#include <net/ethernet.h> 53150957Simp#include <net/if.h> 54257176Sglebius#include <net/if_var.h> 55150957Simp#include <net/if_arp.h> 56150957Simp#include <net/if_dl.h> 57150957Simp#include <net/if_mib.h> 58150957Simp#include <net/if_media.h> 59150957Simp 60150957Simp#include <net/bpf.h> 61150957Simp 62150957Simp#include <dev/ed/if_edreg.h> 63150957Simp#include <dev/ed/if_edvar.h> 64150957Simp#include <dev/ed/rtl80x9reg.h> 65150957Simp 66150957Simpstatic int ed_rtl_set_media(struct ifnet *ifp); 67150957Simpstatic void ed_rtl_get_media(struct ifnet *ifp, struct ifmediareq *); 68150957Simp 69150957Simpstatic int 70150957Simped_rtl80x9_media_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command) 71150957Simp{ 72150957Simp return (ifmedia_ioctl(sc->ifp, ifr, &sc->ifmedia, command)); 73150957Simp} 74150957Simp 75150957Simpint 76150957Simped_probe_RTL80x9(device_t dev, int port_rid, int flags) 77150957Simp{ 78150957Simp struct ed_softc *sc = device_get_softc(dev); 79151299Simp char *ts; 80150957Simp int error; 81150957Simp 82150957Simp if ((error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS))) 83150957Simp return (error); 84151547Simp 85151547Simp sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 86151547Simp sc->nic_offset = ED_NOVELL_NIC_OFFSET; 87150957Simp 88150957Simp if (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_PS0 | ED_CR_PS1)) 89150957Simp ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 90150957Simp 91150957Simp if (ed_nic_inb(sc, ED_RTL80X9_80X9ID0) != ED_RTL80X9_ID0) 92150957Simp return (ENXIO); 93150957Simp 94150957Simp switch (ed_nic_inb(sc, ED_RTL80X9_80X9ID1)) { 95150957Simp case ED_RTL8019_ID1: 96150957Simp sc->chip_type = ED_CHIP_TYPE_RTL8019; 97151299Simp ts = "RTL8019"; 98150957Simp break; 99150957Simp case ED_RTL8029_ID1: 100150957Simp sc->chip_type = ED_CHIP_TYPE_RTL8029; 101151299Simp ts = "RTL8029"; 102150957Simp break; 103150957Simp default: 104150957Simp return (ENXIO); 105150957Simp } 106150957Simp 107150957Simp if ((error = ed_probe_Novell_generic(dev, flags))) 108150957Simp return (error); 109150957Simp 110151299Simp sc->type_str = ts; 111150957Simp sc->sc_media_ioctl = &ed_rtl80x9_media_ioctl; 112150957Simp ifmedia_init(&sc->ifmedia, 0, ed_rtl_set_media, ed_rtl_get_media); 113150957Simp 114150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, 0); 115150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, 0); 116150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_2, 0, 0); 117150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_5, 0, 0); 118150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, 0); 119150957Simp 120260050Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 121260050Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 122150957Simp ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_3 | ED_CR_STP); 123260050Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 124260050Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 125150957Simp 126150957Simp switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) & ED_RTL80X9_CF2_MEDIA) { 127150957Simp case ED_RTL80X9_CF2_AUTO: 128150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); 129150957Simp break; 130150957Simp case ED_RTL80X9_CF2_10_5: 131150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_5); 132150957Simp break; 133150957Simp case ED_RTL80X9_CF2_10_2: 134150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_2); 135150957Simp break; 136150957Simp case ED_RTL80X9_CF2_10_T: 137150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | 138151299Simp ((ed_nic_inb(sc, ED_RTL80X9_CONFIG3) 139151299Simp & ED_RTL80X9_CF3_FUDUP) ? IFM_FDX : 0)); 140150957Simp break; 141150957Simp } 142150957Simp return (0); 143150957Simp} 144150957Simp 145150957Simpstatic int 146150957Simped_rtl_set_media(struct ifnet *ifp) 147150957Simp{ 148150957Simp struct ed_softc *sc; 149150957Simp 150150957Simp sc = ifp->if_softc; 151150957Simp ED_LOCK(sc); 152260050Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 153260050Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 154150957Simp ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 155150957Simp | (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP))); 156260050Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 157260050Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 158150957Simp 159150957Simp switch(IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) { 160150957Simp case IFM_10_T: 161150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_T 162150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 163150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 164150957Simp break; 165150957Simp case IFM_10_2: 166150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_2 167150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 168150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 169150957Simp break; 170150957Simp case IFM_10_5: 171150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_5 172150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 173150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 174150957Simp break; 175150957Simp case IFM_AUTO: 176150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_AUTO 177150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 178150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 179150957Simp break; 180150957Simp } 181150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG3, 182150957Simp (sc->ifmedia.ifm_cur->ifm_media & IFM_FDX) ? 183150957Simp (ed_nic_inb(sc, ED_RTL80X9_CONFIG3) | ED_RTL80X9_CF3_FUDUP) : 184150957Simp (ed_nic_inb(sc, ED_RTL80X9_CONFIG3) & ~ED_RTL80X9_CF3_FUDUP)); 185150957Simp 186150957Simp ED_UNLOCK(sc); 187150957Simp return (0); 188150957Simp} 189150957Simp 190150957Simpstatic void 191150957Simped_rtl_get_media(struct ifnet *ifp, struct ifmediareq *imr) 192150957Simp{ 193150957Simp struct ed_softc *sc; 194150957Simp 195150957Simp sc = ifp->if_softc; 196150957Simp imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media; 197150957Simp 198150957Simp 199150957Simp if (IFM_SUBTYPE(imr->ifm_active) == IFM_AUTO) { 200150957Simp ED_LOCK(sc); 201260050Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 202260050Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 203150957Simp ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 | 204150957Simp (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP))); 205260050Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 206260050Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 207150957Simp 208150957Simp switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG0) 209175006Simp & (sc->chip_type == ED_CHIP_TYPE_RTL8029 ? ED_RTL80X9_CF0_BNC 210150957Simp : (ED_RTL80X9_CF0_AUI | ED_RTL80X9_CF0_BNC))) { 211150957Simp case ED_RTL80X9_CF0_BNC: 212150957Simp imr->ifm_active |= IFM_10_2; 213150957Simp break; 214150957Simp case ED_RTL80X9_CF0_AUI: 215150957Simp imr->ifm_active |= IFM_10_5; 216150957Simp break; 217150957Simp default: 218150957Simp imr->ifm_active |= IFM_10_T; 219150957Simp break; 220150957Simp } 221150957Simp ED_UNLOCK(sc); 222150957Simp } 223150957Simp imr->ifm_status = 0; 224150957Simp} 225150957Simp 226