if_ed_rtl80x9.c revision 175006
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: head/sys/dev/ed/if_ed_rtl80x9.c 175006 2007-12-31 03:27:21Z imp $"); 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> 54150957Simp#include <net/if_arp.h> 55150957Simp#include <net/if_dl.h> 56150957Simp#include <net/if_mib.h> 57150957Simp#include <net/if_media.h> 58150957Simp 59150957Simp#include <net/bpf.h> 60150957Simp 61150957Simp#include <dev/ed/if_edreg.h> 62150957Simp#include <dev/ed/if_edvar.h> 63150957Simp#include <dev/ed/rtl80x9reg.h> 64150957Simp 65150957Simpstatic int ed_rtl_set_media(struct ifnet *ifp); 66150957Simpstatic void ed_rtl_get_media(struct ifnet *ifp, struct ifmediareq *); 67150957Simp 68150957Simpstatic int 69150957Simped_rtl80x9_media_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command) 70150957Simp{ 71150957Simp return (ifmedia_ioctl(sc->ifp, ifr, &sc->ifmedia, command)); 72150957Simp} 73150957Simp 74150957Simpint 75150957Simped_probe_RTL80x9(device_t dev, int port_rid, int flags) 76150957Simp{ 77150957Simp struct ed_softc *sc = device_get_softc(dev); 78151299Simp char *ts; 79150957Simp int error; 80150957Simp 81150957Simp if ((error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS))) 82150957Simp return (error); 83151547Simp 84151547Simp sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 85151547Simp sc->nic_offset = ED_NOVELL_NIC_OFFSET; 86150957Simp 87150957Simp if (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_PS0 | ED_CR_PS1)) 88150957Simp ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 89150957Simp 90150957Simp if (ed_nic_inb(sc, ED_RTL80X9_80X9ID0) != ED_RTL80X9_ID0) 91150957Simp return (ENXIO); 92150957Simp 93150957Simp switch (ed_nic_inb(sc, ED_RTL80X9_80X9ID1)) { 94150957Simp case ED_RTL8019_ID1: 95150957Simp sc->chip_type = ED_CHIP_TYPE_RTL8019; 96151299Simp ts = "RTL8019"; 97150957Simp break; 98150957Simp case ED_RTL8029_ID1: 99150957Simp sc->chip_type = ED_CHIP_TYPE_RTL8029; 100151299Simp ts = "RTL8029"; 101150957Simp break; 102150957Simp default: 103150957Simp return (ENXIO); 104150957Simp } 105150957Simp 106150957Simp if ((error = ed_probe_Novell_generic(dev, flags))) 107150957Simp return (error); 108150957Simp 109151299Simp sc->type_str = ts; 110150957Simp sc->sc_media_ioctl = &ed_rtl80x9_media_ioctl; 111150957Simp ifmedia_init(&sc->ifmedia, 0, ed_rtl_set_media, ed_rtl_get_media); 112150957Simp 113150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, 0); 114150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, 0); 115150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_2, 0, 0); 116150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_5, 0, 0); 117150957Simp ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, 0); 118150957Simp 119150957Simp ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_3 | ED_CR_STP); 120150957Simp 121150957Simp switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) & ED_RTL80X9_CF2_MEDIA) { 122150957Simp case ED_RTL80X9_CF2_AUTO: 123150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); 124150957Simp break; 125150957Simp case ED_RTL80X9_CF2_10_5: 126150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_5); 127150957Simp break; 128150957Simp case ED_RTL80X9_CF2_10_2: 129150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_2); 130150957Simp break; 131150957Simp case ED_RTL80X9_CF2_10_T: 132150957Simp ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T | 133151299Simp ((ed_nic_inb(sc, ED_RTL80X9_CONFIG3) 134151299Simp & ED_RTL80X9_CF3_FUDUP) ? IFM_FDX : 0)); 135150957Simp break; 136150957Simp } 137150957Simp return (0); 138150957Simp} 139150957Simp 140150957Simpstatic int 141150957Simped_rtl_set_media(struct ifnet *ifp) 142150957Simp{ 143150957Simp struct ed_softc *sc; 144150957Simp 145150957Simp sc = ifp->if_softc; 146150957Simp ED_LOCK(sc); 147150957Simp ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 148150957Simp | (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP))); 149150957Simp 150150957Simp switch(IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) { 151150957Simp case IFM_10_T: 152150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_T 153150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 154150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 155150957Simp break; 156150957Simp case IFM_10_2: 157150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_2 158150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 159150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 160150957Simp break; 161150957Simp case IFM_10_5: 162150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_5 163150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 164150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 165150957Simp break; 166150957Simp case IFM_AUTO: 167150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_AUTO 168150957Simp | (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) 169150957Simp & ~ED_RTL80X9_CF2_MEDIA)); 170150957Simp break; 171150957Simp } 172150957Simp ed_nic_outb(sc, ED_RTL80X9_CONFIG3, 173150957Simp (sc->ifmedia.ifm_cur->ifm_media & IFM_FDX) ? 174150957Simp (ed_nic_inb(sc, ED_RTL80X9_CONFIG3) | ED_RTL80X9_CF3_FUDUP) : 175150957Simp (ed_nic_inb(sc, ED_RTL80X9_CONFIG3) & ~ED_RTL80X9_CF3_FUDUP)); 176150957Simp 177150957Simp ED_UNLOCK(sc); 178150957Simp return (0); 179150957Simp} 180150957Simp 181150957Simpstatic void 182150957Simped_rtl_get_media(struct ifnet *ifp, struct ifmediareq *imr) 183150957Simp{ 184150957Simp struct ed_softc *sc; 185150957Simp 186150957Simp sc = ifp->if_softc; 187150957Simp imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media; 188150957Simp 189150957Simp 190150957Simp if (IFM_SUBTYPE(imr->ifm_active) == IFM_AUTO) { 191150957Simp ED_LOCK(sc); 192150957Simp ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 | 193150957Simp (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP))); 194150957Simp 195150957Simp switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG0) 196175006Simp & (sc->chip_type == ED_CHIP_TYPE_RTL8029 ? ED_RTL80X9_CF0_BNC 197150957Simp : (ED_RTL80X9_CF0_AUI | ED_RTL80X9_CF0_BNC))) { 198150957Simp case ED_RTL80X9_CF0_BNC: 199150957Simp imr->ifm_active |= IFM_10_2; 200150957Simp break; 201150957Simp case ED_RTL80X9_CF0_AUI: 202150957Simp imr->ifm_active |= IFM_10_5; 203150957Simp break; 204150957Simp default: 205150957Simp imr->ifm_active |= IFM_10_T; 206150957Simp break; 207150957Simp } 208150957Simp ED_UNLOCK(sc); 209150957Simp } 210150957Simp imr->ifm_status = 0; 211150957Simp} 212150957Simp 213