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

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

1.1     ! nbrk        1: /*     $OpenBSD: if_san_common.c,v 1.11 2005/11/08 20:23:42 canacar Exp $      */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 2001-2004 Sangoma Technologies (SAN)
        !             5:  * All rights reserved.  www.sangoma.com
        !             6:  *
        !             7:  * This code is written by Alex Feldman <al.feldman@sangoma.com> for SAN.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above
        !            15:  *    copyright notice, this list of conditions and the following disclaimer
        !            16:  *    in the documentation and/or other materials provided with the
        !            17:  *    distribution.
        !            18:  * 3. Neither the name of Sangoma Technologies nor the names of its
        !            19:  *    contributors may be used to endorse or promote products derived
        !            20:  *    from this software without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY SANGOMA TECHNOLOGIES AND CONTRIBUTORS
        !            23:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            24:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            25:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            26:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            27:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            28:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            29:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            32:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35:
        !            36: # include <sys/types.h>
        !            37: # include <sys/param.h>
        !            38: # include <sys/systm.h>
        !            39: # include <sys/syslog.h>
        !            40: # include <sys/ioccom.h>
        !            41: # include <sys/conf.h>
        !            42: # include <sys/malloc.h>
        !            43: # include <sys/errno.h>
        !            44: # include <sys/exec.h>
        !            45: # include <sys/mbuf.h>
        !            46: # include <sys/proc.h>
        !            47: # include <sys/socket.h>
        !            48: # include <sys/kernel.h>
        !            49: # include <sys/time.h>
        !            50: # include <sys/timeout.h>
        !            51:
        !            52: # include <net/bpf.h>
        !            53: # include <net/if_dl.h>
        !            54: # include <net/if_types.h>
        !            55: # include <net/if.h>
        !            56: # include <net/netisr.h>
        !            57: # include <net/route.h>
        !            58: # include <net/if_media.h>
        !            59: # include <net/ppp_defs.h>
        !            60: # include <net/if_ppp.h>
        !            61: # include <net/if_sppp.h>
        !            62: # include <netinet/in_systm.h>
        !            63: # include <netinet/in.h>
        !            64: # include <netinet/in_var.h>
        !            65: # include <netinet/udp.h>
        !            66: # include <netinet/ip.h>
        !            67:
        !            68: # include <dev/pci/if_san_common.h>
        !            69: # include <dev/pci/if_san_obsd.h>
        !            70:
        !            71: #ifdef _DEBUG_
        !            72: #define        STATIC
        !            73: #else
        !            74: #define        STATIC          static
        !            75: #endif
        !            76:
        !            77: /* WAN link driver entry points */
        !            78: #if 0
        !            79: static int     shutdown(sdla_t *card);
        !            80: #endif
        !            81:
        !            82: /* Miscellaneous functions */
        !            83: static int wan_ioctl(struct ifnet*, int, struct ifreq *);
        !            84: static int sdla_isr(void *);
        !            85:
        !            86: static void release_hw(sdla_t *card);
        !            87:
        !            88: static int wan_ioctl_dump(sdla_t *, void *);
        !            89: static int wan_ioctl_hwprobe(struct ifnet *, void *);
        !            90:
        !            91: /*
        !            92:  * Global Data
        !            93:  * Note: All data must be explicitly initialized!!!
        !            94:  */
        !            95:
        !            96: /* private data */
        !            97: extern char    *san_drvname;
        !            98: LIST_HEAD(, sdla) wan_cardlist = LIST_HEAD_INITIALIZER(&wan_cardlist);
        !            99:
        !           100: #if 0
        !           101: static san_detach(void)
        !           102: {
        !           103:        wanpipe_common_t        *common;
        !           104:        sdla_t                  *card, *tmp_card;
        !           105:        int                     err = 0;
        !           106:
        !           107:        card = LIST_FIRST(&wan_cardlist);
        !           108:        while (card) {
        !           109:                if (card->disable_comm)
        !           110:                        card->disable_comm(card);
        !           111:
        !           112:                while ((common = LIST_FIRST(&card->dev_head))) {
        !           113:                        LIST_REMOVE(common, next);
        !           114:                        if (card->del_if) {
        !           115:                                struct ifnet *ifp =
        !           116:                                    (struct ifnet*)&common->ifp;
        !           117:                                log(LOG_INFO, "%s: Deleting interface...\n",
        !           118:                                                ifp->if_xname);
        !           119:                                card->del_if(card, ifp);
        !           120:                        }
        !           121:                }
        !           122:                log(LOG_INFO, "%s: Shutdown device\n", card->devname);
        !           123:                shutdown(card);
        !           124:                tmp_card = card;
        !           125:                card = LIST_NEXT(card, next);
        !           126:                LIST_REMOVE(tmp_card, next);
        !           127:                free(tmp_card, M_DEVBUF);
        !           128:        }
        !           129:
        !           130:        log(LOG_INFO, "\n");
        !           131:        log(LOG_INFO, "%s: WANPIPE Generic Modules Unloaded.\n",
        !           132:                                                san_drvname);
        !           133:
        !           134:        err = sdladrv_exit();
        !           135:        return err;
        !           136: }
        !           137: #endif
        !           138:
        !           139:
        !           140: int
        !           141: san_dev_attach(void *hw, u_int8_t *devname, int namelen)
        !           142: {
        !           143:        sdla_t                  *card;
        !           144:        wanpipe_common_t        *common = NULL;
        !           145:        int                     err = 0;
        !           146:
        !           147:        card=malloc(sizeof(sdla_t), M_DEVBUF, M_NOWAIT);
        !           148:        if (!card) {
        !           149:                log(LOG_INFO, "%s: Failed allocate new card!\n",
        !           150:                                san_drvname);
        !           151:                return (EINVAL);
        !           152:        }
        !           153:        bzero(card, sizeof(sdla_t));
        !           154:        card->magic = WANPIPE_MAGIC;
        !           155:        wanpipe_generic_name(card, card->devname, sizeof(card->devname));
        !           156:        strlcpy(devname, card->devname, namelen);
        !           157:        card->hw = hw;
        !           158:        LIST_INIT(&card->dev_head);
        !           159:
        !           160:        sdla_getcfg(card->hw, SDLA_CARDTYPE, &card->type);
        !           161:        if (sdla_is_te1(card->hw))
        !           162:                sdla_te_defcfg(&card->fe_te.te_cfg);
        !           163:
        !           164:        err = sdla_setup(card->hw);
        !           165:        if (err) {
        !           166:                log(LOG_INFO, "%s: Hardware setup Failed %d\n",
        !           167:                        card->devname,err);
        !           168:                return (EINVAL);
        !           169:        }
        !           170:        err = sdla_intr_establish(card->hw, sdla_isr, (void*)card);
        !           171:        if (err) {
        !           172:                log(LOG_INFO, "%s: Failed set interrupt handler!\n",
        !           173:                                        card->devname);
        !           174:                sdla_down(card->hw);
        !           175:                return (EINVAL);
        !           176:        }
        !           177:
        !           178:        switch (card->type) {
        !           179:        case SDLA_AFT:
        !           180: #if defined(DEBUG_INIT)
        !           181:                log(LOG_INFO, "%s: Starting AFT Hardware Init.\n",
        !           182:                                card->devname);
        !           183: #endif
        !           184:                common = wan_xilinx_init(card);
        !           185:                break;
        !           186:        }
        !           187:        if (common == NULL) {
        !           188:                release_hw(card);
        !           189:                card->configured = 0;
        !           190:                return (EINVAL);
        !           191:        }
        !           192:        LIST_INSERT_HEAD(&card->dev_head, common, next);
        !           193:
        !           194:        /* Reserve I/O region and schedule background task */
        !           195:        card->critical  = 0;
        !           196:        card->state     = WAN_DISCONNECTED;
        !           197:        card->ioctl     = wan_ioctl;
        !           198:        return (0);
        !           199: }
        !           200:
        !           201:
        !           202: /*
        !           203:  * Shut down WAN link driver.
        !           204:  * o shut down adapter hardware
        !           205:  * o release system resources.
        !           206:  *
        !           207:  */
        !           208: #if 0
        !           209: static int
        !           210: shutdown (sdla_t *card)
        !           211: {
        !           212:        int err=0;
        !           213:
        !           214:        if (card->state == WAN_UNCONFIGURED) {
        !           215:                return 0;
        !           216:        }
        !           217:        card->state = WAN_UNCONFIGURED;
        !           218:
        !           219:        bit_set((u_int8_t*)&card->critical, PERI_CRIT);
        !           220:
        !           221:        /* In case of piggibacking, make sure that
        !           222:          * we never try to shutdown both devices at the same
        !           223:          * time, because they depend on one another */
        !           224:
        !           225:        card->state = WAN_UNCONFIGURED;
        !           226:
        !           227:        /* Release Resources */
        !           228:        release_hw(card);
        !           229:
        !           230:         /* only free the allocated I/O range if not an S514 adapter */
        !           231:        if (!card->configured) {
        !           232:                card->hw = NULL;
        !           233:                if (card->same_cpu) {
        !           234:                        card->same_cpu->hw = NULL;
        !           235:                        card->same_cpu->same_cpu = NULL;
        !           236:                        card->same_cpu=NULL;
        !           237:                }
        !           238:        }
        !           239:
        !           240:        bit_clear((u_int8_t*)&card->critical, PERI_CRIT);
        !           241:
        !           242:        return err;
        !           243: }
        !           244: #endif
        !           245:
        !           246: static void
        !           247: release_hw(sdla_t *card)
        !           248: {
        !           249:        log(LOG_INFO, "%s: Master shutting down\n",card->devname);
        !           250:        sdla_down(card->hw);
        !           251:        sdla_intr_disestablish(card->hw);
        !           252:        card->configured = 0;
        !           253:        return;
        !           254: }
        !           255:
        !           256:
        !           257: /*
        !           258:  * Driver IOCTL Handlers
        !           259:  */
        !           260:
        !           261: static int
        !           262: wan_ioctl(struct ifnet *ifp, int cmd, struct ifreq *ifr)
        !           263: {
        !           264:        sdla_t                  *card;
        !           265:        wanpipe_common_t        *common = WAN_IFP_TO_COMMON(ifp);
        !           266:        int                     err;
        !           267:
        !           268:        SAN_ASSERT(common == NULL);
        !           269:        SAN_ASSERT(common->card == NULL);
        !           270:
        !           271:        if ((err = suser(curproc, 0)) != 0)
        !           272:                return err;
        !           273:
        !           274:        switch (cmd) {
        !           275:        case SIOC_WANPIPE_HWPROBE:
        !           276:                err = wan_ioctl_hwprobe(ifp, ifr->ifr_data);
        !           277:                break;
        !           278:
        !           279:        case SIOC_WANPIPE_DUMP:
        !           280:                err = wan_ioctl_dump(card, ifr->ifr_data);
        !           281:                break;
        !           282:
        !           283:        default:
        !           284:                err = ENOTTY;
        !           285:                break;
        !           286:        }
        !           287:        return err;
        !           288: }
        !           289:
        !           290: static int
        !           291: wan_ioctl_hwprobe(struct ifnet *ifp, void *u_def)
        !           292: {
        !           293:        sdla_t                  *card = NULL;
        !           294:        wanpipe_common_t        *common = WAN_IFP_TO_COMMON(ifp);
        !           295:        wanlite_def_t           def;
        !           296:        unsigned char           *str;
        !           297:        int                     err;
        !           298:
        !           299:        SAN_ASSERT(common == NULL);
        !           300:        SAN_ASSERT(common->card == NULL);
        !           301:        card = common->card;
        !           302:        bzero(&def, sizeof(wanlite_def_t));
        !           303:        /* Get protocol type */
        !           304:        def.proto = common->protocol;
        !           305:
        !           306:        /* Get hardware configuration */
        !           307:        err = sdla_get_hwprobe(card->hw, (void**)&str);
        !           308:        if (err)
        !           309:                return EINVAL;
        !           310:
        !           311:        strlcpy(def.hwprobe, str, sizeof(def.hwprobe));
        !           312:        /* Get interface configuration */
        !           313:        if (IS_TE1(&card->fe_te.te_cfg)) {
        !           314:                if (IS_T1(&card->fe_te.te_cfg))
        !           315:                        def.iface = IF_IFACE_T1;
        !           316:                else
        !           317:                        def.iface = IF_IFACE_E1;
        !           318:
        !           319:                bcopy(&card->fe_te.te_cfg, &def.te_cfg, sizeof(sdla_te_cfg_t));
        !           320:        }
        !           321:
        !           322:        err = copyout(&def, u_def, sizeof(def));
        !           323:        if (err) {
        !           324:                log(LOG_INFO, "%s: Failed to copy to user space (%d)\n",
        !           325:                    card->devname, __LINE__);
        !           326:                return ENOMEM;
        !           327:        }
        !           328:        return 0;
        !           329: }
        !           330:
        !           331: static int
        !           332: wan_ioctl_dump(sdla_t *card, void *u_dump)
        !           333: {
        !           334:        sdla_dump_t     dump;
        !           335:        void*           data;
        !           336:        u_int32_t       memory;
        !           337:        int             err = 0;
        !           338:
        !           339:        err = copyin(u_dump, &dump, sizeof(sdla_dump_t));
        !           340:        if (err)
        !           341:                return err;
        !           342:
        !           343:        sdla_getcfg(card->hw, SDLA_MEMORY, &memory);
        !           344:        if (dump.magic != WANPIPE_MAGIC)
        !           345:                return EINVAL;
        !           346:
        !           347:        if ((dump.offset + dump.length) > memory)
        !           348:                return EINVAL;
        !           349:
        !           350:        data = malloc(dump.length, M_DEVBUF, M_NOWAIT);
        !           351:        if (data == NULL)
        !           352:                return ENOMEM;
        !           353:
        !           354:        sdla_peek(card->hw, dump.offset, data, dump.length);
        !           355:        err = copyout(data, dump.ptr, dump.length);
        !           356:        if (err) {
        !           357:                log(LOG_INFO, "%s: Failed to copy to user space (%d)\n",
        !           358:                                card->devname, __LINE__);
        !           359:        }
        !           360:        free(data, M_DEVBUF);
        !           361:        return err;
        !           362: }
        !           363:
        !           364:
        !           365: /*
        !           366:  * SDLA Interrupt Service Routine.
        !           367:  * o call protocol-specific interrupt service routine, if any.
        !           368:  */
        !           369: int
        !           370: sdla_isr(void *pcard)
        !           371: {
        !           372:        sdla_t *card = (sdla_t*)pcard;
        !           373:
        !           374:        if (card == NULL || card->magic != WANPIPE_MAGIC)
        !           375:                return 0;
        !           376:
        !           377:        switch (card->type) {
        !           378:        case SDLA_AFT:
        !           379:                if (card->isr)
        !           380:                        card->isr(card);
        !           381:                break;
        !           382:        }
        !           383:        return (1);
        !           384: }
        !           385:
        !           386: struct mbuf*
        !           387: wan_mbuf_alloc(int len)
        !           388: {
        !           389:        struct mbuf     *m;
        !           390:
        !           391:        /* XXX handle len > MCLBYTES */
        !           392:        if (len <= 0 || len > MCLBYTES)
        !           393:                return (NULL);
        !           394:
        !           395:        MGETHDR(m, M_DONTWAIT, MT_DATA);
        !           396:
        !           397:        if (m == NULL || len <= MHLEN)
        !           398:                return (m);
        !           399:
        !           400:        m->m_pkthdr.len = len;
        !           401:        m->m_len = len;
        !           402:        MCLGET(m, M_DONTWAIT);
        !           403:
        !           404:        if ((m->m_flags & M_EXT) == 0) {
        !           405:                m_freem(m);
        !           406:                return (NULL);
        !           407:        }
        !           408:
        !           409:        return (m);
        !           410: }
        !           411:
        !           412: int
        !           413: wan_mbuf_to_buffer(struct mbuf **m_org)
        !           414: {
        !           415:        struct mbuf     *m, *m0, *tmp;
        !           416:        char            *buffer;
        !           417:        size_t           len;
        !           418:
        !           419:        if (m_org == NULL || *m_org == NULL)
        !           420:                return (EINVAL);
        !           421:
        !           422:        m0 = *m_org;
        !           423: #if 0
        !           424:        /* no need to copy if it is a single, properly aligned mbuf */
        !           425:        if (m0->m_next == NULL && (mtod(m0, u_int32_t)  & 0x03) == 0)
        !           426:                return (0);
        !           427: #endif
        !           428:        MGET(m, M_DONTWAIT, MT_DATA);
        !           429:
        !           430:        if (m == NULL)
        !           431:                return (ENOMEM);
        !           432:
        !           433:        MCLGET(m, M_DONTWAIT);
        !           434:
        !           435:        if ((m->m_flags & M_EXT) == 0) {
        !           436:                m_freem(m);
        !           437:                return (ENOMEM);
        !           438:        }
        !           439:
        !           440:        m->m_len = 0;
        !           441:
        !           442:        /* XXX handle larger packets? */
        !           443:        len = MCLBYTES ;
        !           444:        buffer = mtod(m, caddr_t);
        !           445:
        !           446:        len -= 16;
        !           447:        buffer += 16;
        !           448:
        !           449:        /* make sure the buffer is aligned to a 4-byte boundary */
        !           450:        if (ADDR_MASK(buffer, 0x03)) {
        !           451:                unsigned int inc = 4 - ADDR_MASK(buffer, 0x03);
        !           452:                buffer += inc;
        !           453:                len -= inc;
        !           454:        }
        !           455:
        !           456:        m->m_data = buffer;
        !           457:
        !           458:        for (tmp = m0; tmp; tmp = tmp->m_next) {
        !           459:                if (tmp->m_len > len) {
        !           460:                        m_freem(m);
        !           461:                        return (EINVAL);
        !           462:                }
        !           463:                bcopy(mtod(tmp, caddr_t), buffer, tmp->m_len);
        !           464:                buffer += tmp->m_len;
        !           465:                m->m_len += tmp->m_len;
        !           466:                len -= tmp->m_len;
        !           467:        }
        !           468:
        !           469:        m_freem(m0);
        !           470:        *m_org = m;
        !           471:
        !           472:        return (0);
        !           473: }

CVSweb