[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

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