[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

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