[BACK]Return to if_re_pci.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/if_re_pci.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: if_re_pci.c,v 1.19 2006/11/28 20:04:02 brad Exp $     */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2005 Peter Valchev <pvalchev@openbsd.org>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: /*
        !            20:  * PCI front-end for the Realtek 8169
        !            21:  */
        !            22:
        !            23: #include <sys/param.h>
        !            24: #include <sys/endian.h>
        !            25: #include <sys/systm.h>
        !            26: #include <sys/sockio.h>
        !            27: #include <sys/mbuf.h>
        !            28: #include <sys/malloc.h>
        !            29: #include <sys/kernel.h>
        !            30: #include <sys/device.h>
        !            31: #include <sys/timeout.h>
        !            32: #include <sys/socket.h>
        !            33:
        !            34: #include <net/if.h>
        !            35: #include <net/if_dl.h>
        !            36: #include <net/if_media.h>
        !            37:
        !            38: #ifdef INET
        !            39: #include <netinet/in.h>
        !            40: #include <netinet/in_systm.h>
        !            41: #include <netinet/in_var.h>
        !            42: #include <netinet/ip.h>
        !            43: #include <netinet/if_ether.h>
        !            44: #endif
        !            45:
        !            46: #include <dev/mii/mii.h>
        !            47: #include <dev/mii/miivar.h>
        !            48:
        !            49: #include <dev/pci/pcireg.h>
        !            50: #include <dev/pci/pcivar.h>
        !            51: #include <dev/pci/pcidevs.h>
        !            52:
        !            53: #include <dev/ic/rtl81x9reg.h>
        !            54: #include <dev/ic/revar.h>
        !            55:
        !            56: struct re_pci_softc {
        !            57:        /* General */
        !            58:        struct rl_softc sc_rl;
        !            59:
        !            60:        /* PCI-specific data */
        !            61:        void *sc_ih;
        !            62:        pci_chipset_tag_t sc_pc;
        !            63:        pcitag_t sc_pcitag;
        !            64: };
        !            65:
        !            66: const struct pci_matchid re_pci_devices[] = {
        !            67:        { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8101E },
        !            68:        { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8168 },
        !            69:        { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169 },
        !            70:        { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169SC },
        !            71:        { PCI_VENDOR_COREGA, PCI_PRODUCT_COREGA_CGLAPCIGT },
        !            72:        { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE528T },
        !            73:        { PCI_VENDOR_USR2, PCI_PRODUCT_USR2_USR997902 },
        !            74:        { PCI_VENDOR_TTTECH, PCI_PRODUCT_TTTECH_MC322 }
        !            75: };
        !            76:
        !            77: #define RE_LINKSYS_EG1032_SUBID 0x00241737
        !            78:
        !            79: int    re_pci_probe(struct device *, void *, void *);
        !            80: void   re_pci_attach(struct device *, struct device *, void *);
        !            81:
        !            82: /*
        !            83:  * PCI autoconfig definitions
        !            84:  */
        !            85: struct cfattach re_pci_ca = {
        !            86:        sizeof(struct re_pci_softc),
        !            87:        re_pci_probe,
        !            88:        re_pci_attach
        !            89: };
        !            90:
        !            91: /*
        !            92:  * Probe for a Realtek 8169/8110 chip. Check the PCI vendor and device
        !            93:  * IDs against our list and return a device name if we find a match.
        !            94:  */
        !            95: int
        !            96: re_pci_probe(struct device *parent, void *match, void *aux)
        !            97: {
        !            98:        struct pci_attach_args *pa = aux;
        !            99:        pci_chipset_tag_t pc = pa->pa_pc;
        !           100:        pcireg_t subid;
        !           101:
        !           102:        subid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
        !           103:
        !           104:        /* C+ mode 8139's */
        !           105:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK &&
        !           106:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8139 &&
        !           107:            PCI_REVISION(pa->pa_class) == 0x20)
        !           108:                return (1);
        !           109:
        !           110:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LINKSYS &&
        !           111:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LINKSYS_EG1032 &&
        !           112:            subid == RE_LINKSYS_EG1032_SUBID)
        !           113:                return (1);
        !           114:
        !           115:        return (pci_matchbyid((struct pci_attach_args *)aux, re_pci_devices,
        !           116:            sizeof(re_pci_devices)/sizeof(re_pci_devices[0])));
        !           117: }
        !           118:
        !           119: /*
        !           120:  * PCI-specific attach routine
        !           121:  */
        !           122: void
        !           123: re_pci_attach(struct device *parent, struct device *self, void *aux)
        !           124: {
        !           125:        struct re_pci_softc     *psc = (struct re_pci_softc *)self;
        !           126:        struct rl_softc         *sc = &psc->sc_rl;
        !           127:        struct pci_attach_args  *pa = aux;
        !           128:        pci_chipset_tag_t       pc = pa->pa_pc;
        !           129:        pci_intr_handle_t       ih;
        !           130:        const char              *intrstr = NULL;
        !           131:        bus_size_t              iosize;
        !           132:        pcireg_t                command;
        !           133:
        !           134:        /*
        !           135:         * Handle power management nonsense.
        !           136:         */
        !           137:
        !           138:        command = pci_conf_read(pc, pa->pa_tag, RL_PCI_CAPID) & 0x000000FF;
        !           139:
        !           140:        if (command == 0x01) {
        !           141:                u_int32_t               iobase, membase, irq;
        !           142:
        !           143:                /* Save important PCI config data. */
        !           144:                iobase = pci_conf_read(pc, pa->pa_tag,  RL_PCI_LOIO);
        !           145:                membase = pci_conf_read(pc, pa->pa_tag, RL_PCI_LOMEM);
        !           146:                irq = pci_conf_read(pc, pa->pa_tag, RL_PCI_INTLINE);
        !           147:
        !           148: #if 0
        !           149:                /* Reset the power state. */
        !           150:                printf(": chip is in D%d power mode "
        !           151:                    "-- setting to D0", command & RL_PSTATE_MASK);
        !           152: #endif
        !           153:                command &= 0xFFFFFFFC;
        !           154:
        !           155:                /* Restore PCI config data. */
        !           156:                pci_conf_write(pc, pa->pa_tag, RL_PCI_LOIO, iobase);
        !           157:                pci_conf_write(pc, pa->pa_tag, RL_PCI_LOMEM, membase);
        !           158:                pci_conf_write(pc, pa->pa_tag, RL_PCI_INTLINE, irq);
        !           159:        }
        !           160:
        !           161:        /*
        !           162:         * Map control/status registers.
        !           163:         */
        !           164:        if (pci_mapreg_map(pa, RL_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
        !           165:            &sc->rl_btag, &sc->rl_bhandle, NULL, &iosize, 0)) {
        !           166:                if (pci_mapreg_map(pa, RL_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
        !           167:                    &sc->rl_btag, &sc->rl_bhandle, NULL, &iosize, 0)) {
        !           168:                        printf(": can't map mem or i/o space\n");
        !           169:                        return;
        !           170:                }
        !           171:        }
        !           172:
        !           173:        /* Allocate interrupt */
        !           174:        if (pci_intr_map(pa, &ih)) {
        !           175:                printf(": couldn't map interrupt\n");
        !           176:                return;
        !           177:        }
        !           178:        intrstr = pci_intr_string(pc, ih);
        !           179:        psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, re_intr, sc,
        !           180:            sc->sc_dev.dv_xname);
        !           181:        if (psc->sc_ih == NULL) {
        !           182:                printf(": couldn't establish interrupt");
        !           183:                if (intrstr != NULL)
        !           184:                        printf(" at %s", intrstr);
        !           185:                return;
        !           186:        }
        !           187:
        !           188:        sc->sc_dmat = pa->pa_dmat;
        !           189:        sc->sc_flags |= RL_ENABLED;
        !           190:
        !           191:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK) {
        !           192:                if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8139)
        !           193:                        sc->rl_type = RL_8139CPLUS;
        !           194:                else
        !           195:                        sc->rl_type = RL_8169;
        !           196:        } else if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TTTECH &&
        !           197:                   PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TTTECH_MC322)
        !           198:                sc->rl_type = RL_8139CPLUS;
        !           199:        else
        !           200:                sc->rl_type = RL_8169;
        !           201:
        !           202:        /* Call bus-independent attach routine */
        !           203:        re_attach(sc, intrstr);
        !           204: }

CVSweb