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

Annotation of sys/dev/cardbus/if_xl_cardbus.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_xl_cardbus.c,v 1.19 2007/05/05 13:24:03 deraadt Exp $ */
                      2: /*     $NetBSD: if_xl_cardbus.c,v 1.13 2000/03/07 00:32:52 mycroft Exp $       */
                      3:
                      4: /*
                      5:  * CardBus specific routines for 3Com 3C575-family CardBus ethernet adapter
                      6:  *
                      7:  * Copyright (c) 1998 and 1999
                      8:  *       HAYAKAWA Koichi.  All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *      This product includes software developed by the author.
                     21:  * 4. Neither the name of the author nor the names of any co-contributors
                     22:  *    may be used to endorse or promote products derived from this software
                     23:  *    without specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY HAYAKAWA KOICHI ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL TAKESHI OHASHI OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
                     37:  *
                     38:  */
                     39:
                     40: #include "bpfilter.h"
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/mbuf.h>
                     45: #include <sys/socket.h>
                     46: #include <sys/ioctl.h>
                     47: #include <sys/errno.h>
                     48: #include <sys/malloc.h>
                     49: #include <sys/kernel.h>
                     50: #include <sys/proc.h>
                     51: #include <sys/device.h>
                     52:
                     53: #include <net/if.h>
                     54: #include <net/if_dl.h>
                     55: #include <net/if_types.h>
                     56: #include <net/if_media.h>
                     57:
                     58: #ifdef INET
                     59: #include <netinet/in.h>
                     60: #include <netinet/in_systm.h>
                     61: #include <netinet/in_var.h>
                     62: #include <netinet/ip.h>
                     63: #include <netinet/if_ether.h>
                     64: #endif
                     65:
                     66: #include <machine/cpu.h>
                     67: #include <machine/bus.h>
                     68:
                     69: #include <dev/cardbus/cardbusvar.h>
                     70: #include <dev/pci/pcidevs.h>
                     71:
                     72: #include <dev/mii/mii.h>
                     73: #include <dev/mii/miivar.h>
                     74:
                     75: #include <dev/ic/xlreg.h>
                     76:
                     77: #if defined XL_DEBUG
                     78: #define DPRINTF(a) printf a
                     79: #else
                     80: #define DPRINTF(a)
                     81: #endif
                     82:
                     83: #define CARDBUS_3C575BTX_FUNCSTAT_PCIREG  CARDBUS_BASE2_REG  /* means 0x18 */
                     84:
                     85: int xl_cardbus_match(struct device *, void *, void *);
                     86: void xl_cardbus_attach(struct device *, struct device *,void *);
                     87: int xl_cardbus_detach(struct device *, int);
                     88: void xl_cardbus_intr_ack(struct xl_softc *);
                     89:
                     90: #define XL_CARDBUS_BOOMERANG   0x0001
                     91: #define XL_CARDBUS_CYCLONE     0x0002
                     92:
                     93: #define XL_CARDBUS_INTR                0x0004
                     94: #define XL_CARDBUS_INTR_ACK    0x8000
                     95:
                     96: struct xl_cardbus_softc {
                     97:        struct xl_softc sc_softc;
                     98:
                     99:        cardbus_devfunc_t sc_ct;
                    100:        int sc_intrline;
                    101:        u_int8_t sc_cardbus_flags;
                    102:        u_int8_t sc_cardtype;
                    103:
                    104:        /* CardBus function status space.  575B requests it. */
                    105:        bus_space_tag_t sc_funct;
                    106:        bus_space_handle_t sc_funch;
                    107:        bus_size_t sc_funcsize;
                    108:
                    109:        bus_size_t sc_mapsize;          /* size of mapped bus space region */
                    110: };
                    111:
                    112: struct cfattach xl_cardbus_ca = {
                    113:        sizeof(struct xl_cardbus_softc), xl_cardbus_match,
                    114:            xl_cardbus_attach, xl_cardbus_detach
                    115: };
                    116:
                    117: const struct xl_cardbus_product {
                    118:        u_int32_t       ecp_prodid;     /* CardBus product ID */
                    119:        int             ecp_flags;      /* initial softc flags */
                    120:        pcireg_t        ecp_csr;        /* PCI CSR flags */
                    121:        int             ecp_cardtype;   /* card type */
                    122:        const char      *ecp_name;      /* device name */
                    123: } xl_cardbus_products[] = {
                    124:        { PCI_PRODUCT_3COM_3C575,
                    125:          XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM,
                    126:          CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MASTER_ENABLE,
                    127:          XL_CARDBUS_BOOMERANG,
                    128:          "3c575-TX Ethernet" },
                    129:
                    130:        { PCI_PRODUCT_3COM_3CCFE575BT,
                    131:          XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM |
                    132:              XL_FLAG_INVERT_LED_PWR,
                    133:          CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MEM_ENABLE |
                    134:              CARDBUS_COMMAND_MASTER_ENABLE,
                    135:          XL_CARDBUS_CYCLONE,
                    136:          "3c575B-TX Ethernet" },
                    137:
                    138:        { PCI_PRODUCT_3COM_3CCFE575CT,
                    139:          XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM |
                    140:              XL_FLAG_INVERT_MII_PWR,
                    141:          CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MEM_ENABLE |
                    142:              CARDBUS_COMMAND_MASTER_ENABLE,
                    143:          XL_CARDBUS_CYCLONE,
                    144:          "3c575C-TX Ethernet" },
                    145:
                    146:        { PCI_PRODUCT_3COM_3CCFEM656,
                    147:          XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM |
                    148:              XL_FLAG_INVERT_LED_PWR | XL_FLAG_INVERT_MII_PWR,
                    149:          CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MEM_ENABLE |
                    150:              CARDBUS_COMMAND_MASTER_ENABLE,
                    151:          XL_CARDBUS_CYCLONE,
                    152:          "3c656-TX Ethernet" },
                    153:
                    154:        { PCI_PRODUCT_3COM_3CCFEM656B,
                    155:          XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM |
                    156:              XL_FLAG_INVERT_LED_PWR | XL_FLAG_INVERT_MII_PWR,
                    157:          CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MEM_ENABLE |
                    158:              CARDBUS_COMMAND_MASTER_ENABLE,
                    159:          XL_CARDBUS_CYCLONE,
                    160:          "3c656B-TX Ethernet" },
                    161:
                    162:        { PCI_PRODUCT_3COM_3CCFEM656C,
                    163:          XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM |
                    164:              XL_FLAG_INVERT_MII_PWR,
                    165:          CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MEM_ENABLE |
                    166:              CARDBUS_COMMAND_MASTER_ENABLE,
                    167:          XL_CARDBUS_CYCLONE,
                    168:          "3c656C-TX Ethernet" },
                    169:
                    170:        { 0,
                    171:          0,
                    172:          0,
                    173:          0,
                    174:          NULL },
                    175: };
                    176:
                    177: const struct xl_cardbus_product *xl_cardbus_lookup(const struct cardbus_attach_args *);
                    178:
                    179: const struct xl_cardbus_product *
                    180: xl_cardbus_lookup(const struct cardbus_attach_args *ca)
                    181: {
                    182:        const struct xl_cardbus_product *ecp;
                    183:
                    184:        if (CARDBUS_VENDOR(ca->ca_id) != PCI_VENDOR_3COM)
                    185:                return (NULL);
                    186:
                    187:        for (ecp = xl_cardbus_products; ecp->ecp_name != NULL; ecp++)
                    188:                if (CARDBUS_PRODUCT(ca->ca_id) == ecp->ecp_prodid)
                    189:                        return (ecp);
                    190:        return (NULL);
                    191: }
                    192:
                    193: int
                    194: xl_cardbus_match(struct device *parent, void *match, void *aux)
                    195: {
                    196:        struct cardbus_attach_args *ca = aux;
                    197:
                    198:        if (xl_cardbus_lookup(ca) != NULL)
                    199:                return (1);
                    200:
                    201:        return (0);
                    202: }
                    203:
                    204: void
                    205: xl_cardbus_attach(struct device *parent, struct device *self, void *aux)
                    206: {
                    207:        struct xl_cardbus_softc *csc = (void *)self;
                    208:        struct xl_softc *sc = &csc->sc_softc;
                    209:        struct cardbus_attach_args *ca = aux;
                    210:        cardbus_devfunc_t ct = ca->ca_ct;
                    211:        cardbus_chipset_tag_t cc = ct->ct_cc;
                    212:        cardbus_function_tag_t cf = ct->ct_cf;
                    213:        cardbusreg_t iob, command, bhlc;
                    214:        const struct xl_cardbus_product *ecp;
                    215:        bus_space_handle_t ioh;
                    216:        bus_addr_t adr;
                    217:
                    218:        if (Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG, CARDBUS_MAPREG_TYPE_IO, 0,
                    219:            &sc->xl_btag, &ioh, &adr, &csc->sc_mapsize)) {
                    220:                printf(": can't map i/o space\n");
                    221:                return;
                    222:        }
                    223:
                    224:        ecp = xl_cardbus_lookup(ca);
                    225:        if (ecp == NULL) {
                    226:                printf("\n");
                    227:                panic("xl_cardbus_attach: impossible");
                    228:        }
                    229:
                    230:        printf(": 3Com %s", ecp->ecp_name);
                    231:
                    232:        sc->xl_flags = ecp->ecp_flags;
                    233:        sc->sc_dmat = ca->ca_dmat;
                    234:
                    235:        iob = adr;
                    236:        sc->xl_bhandle = ioh;
                    237:
                    238:        (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
                    239:
                    240:        command = cardbus_conf_read(cc, cf, ca->ca_tag,
                    241:            CARDBUS_COMMAND_STATUS_REG);
                    242:        command |= ecp->ecp_csr;
                    243:        csc->sc_cardtype = ecp->ecp_cardtype;
                    244:
                    245:        if (csc->sc_cardtype == XL_CARDBUS_CYCLONE) {
                    246:                /* map CardBus function status window */
                    247:                if (Cardbus_mapreg_map(ct, CARDBUS_BASE2_REG,
                    248:                    CARDBUS_MAPREG_TYPE_MEM, 0, &csc->sc_funct,
                    249:                    &csc->sc_funch, 0, &csc->sc_funcsize)) {
                    250:                        printf("%s: unable to map function status window\n",
                    251:                            self->dv_xname);
                    252:                        return;
                    253:                }
                    254:
                    255:                /*
                    256:                 * Make sure CardBus bridge can access memory space.  Usually
                    257:                 * memory access is enabled by BIOS, but some BIOSes do not
                    258:                 * enable it.
                    259:                 */
                    260:                (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
                    261:        }
                    262:
                    263:        (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
                    264:        cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG,
                    265:            command);
                    266:
                    267:        /*
                    268:         * set latency timer
                    269:         */
                    270:        bhlc = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG);
                    271:        if (CARDBUS_LATTIMER(bhlc) < 0x20) {
                    272:                /* at least the value of latency timer should 0x20. */
                    273:                DPRINTF(("if_xl_cardbus: lattimer 0x%x -> 0x20\n",
                    274:                    CARDBUS_LATTIMER(bhlc)));
                    275:                bhlc &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
                    276:                bhlc |= (0x20 << CARDBUS_LATTIMER_SHIFT);
                    277:                cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG, bhlc);
                    278:        }
                    279:
                    280:        csc->sc_ct = ca->ca_ct;
                    281:        csc->sc_intrline = ca->ca_intrline;
                    282:
                    283:        /* Map and establish the interrupt. */
                    284:
                    285:        sc->xl_intrhand = cardbus_intr_establish(cc, cf, ca->ca_intrline,
                    286:            IPL_NET, xl_intr, csc, self->dv_xname);
                    287:
                    288:        if (sc->xl_intrhand == NULL) {
                    289:                printf(": couldn't establish interrupt");
                    290:                printf(" at %d", ca->ca_intrline);
                    291:                printf("\n");
                    292:                return;
                    293:        }
                    294:        printf(": irq %d", ca->ca_intrline);
                    295:
                    296:        sc->intr_ack = xl_cardbus_intr_ack;
                    297:
                    298:        xl_attach(sc);
                    299:
                    300:        if (csc->sc_cardtype == XL_CARDBUS_CYCLONE)
                    301:                bus_space_write_4(csc->sc_funct, csc->sc_funch,
                    302:                    XL_CARDBUS_INTR, XL_CARDBUS_INTR_ACK);
                    303:
                    304: }
                    305:
                    306: int
                    307: xl_detach(struct xl_softc *sc)
                    308: {
                    309:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    310:        extern void xl_freetxrx(struct xl_softc *);
                    311:
                    312:        /* Unhook our tick handler. */
                    313:        timeout_del(&sc->xl_stsup_tmo);
                    314:
                    315:        xl_freetxrx(sc);
                    316:
                    317:        /* Detach all PHYs */
                    318:        if (sc->xl_hasmii)
                    319:                mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
                    320:
                    321:        /* Delete all remaining media. */
                    322:        ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
                    323:
                    324:        ether_ifdetach(ifp);
                    325:        if_detach(ifp);
                    326:
                    327:        if (sc->sc_sdhook != NULL)
                    328:                shutdownhook_disestablish(sc->sc_sdhook);
                    329:        if (sc->sc_pwrhook != NULL)
                    330:                powerhook_disestablish(sc->sc_pwrhook);
                    331:
                    332:        return (0);
                    333: }
                    334:
                    335: int
                    336: xl_cardbus_detach(struct device *self, int arg)
                    337: {
                    338:        struct xl_cardbus_softc *csc = (void *)self;
                    339:        struct xl_softc *sc = &csc->sc_softc;
                    340:        struct cardbus_devfunc *ct = csc->sc_ct;
                    341:        int rv = 0;
                    342:
                    343: #if defined(DIAGNOSTIC)
                    344:        if (ct == NULL) {
                    345:                panic("%s: data structure lacks", sc->sc_dev.dv_xname);
                    346:        }
                    347: #endif
                    348:
                    349:        rv = xl_detach(sc);
                    350:        if (rv == 0) {
                    351:                /*
                    352:                 * Unhook the interrupt handler.
                    353:                 */
                    354:                cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf,
                    355:                    sc->xl_intrhand);
                    356:
                    357:                if (csc->sc_cardtype == XL_CARDBUS_CYCLONE) {
                    358:                        Cardbus_mapreg_unmap(ct, CARDBUS_BASE2_REG,
                    359:                            csc->sc_funct, csc->sc_funch, csc->sc_funcsize);
                    360:                }
                    361:
                    362:                Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->xl_btag,
                    363:                    sc->xl_bhandle, csc->sc_mapsize);
                    364:        }
                    365:        return (rv);
                    366: }
                    367:
                    368: void
                    369: xl_cardbus_intr_ack(struct xl_softc *sc)
                    370: {
                    371:        struct xl_cardbus_softc *csc = (struct xl_cardbus_softc *)sc;
                    372:
                    373:        bus_space_write_4(csc->sc_funct, csc->sc_funch, XL_CARDBUS_INTR,
                    374:            XL_CARDBUS_INTR_ACK);
                    375: }

CVSweb