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

Annotation of sys/dev/pci/if_san_obsd.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_san_obsd.c,v 1.12 2006/05/13 19:04:30 brad 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: #include <sys/types.h>
                     36: #include <sys/param.h>
                     37: #include <sys/systm.h>
                     38: #include <sys/proc.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/sockio.h>
                     47: #include <sys/socket.h>
                     48: #include <sys/kernel.h>
                     49: #include <sys/device.h>
                     50: #include <sys/time.h>
                     51: #include <sys/timeout.h>
                     52:
                     53: #include "bpfilter.h"
                     54: #if NBPFILTER > 0
                     55: # include <net/bpf.h>
                     56: #endif
                     57: #include <net/if.h>
                     58: #include <net/if_media.h>
                     59: #include <net/netisr.h>
                     60: #include <net/if_sppp.h>
                     61: #include <netinet/in_systm.h>
                     62: #include <netinet/in.h>
                     63:
                     64: #include <netinet/udp.h>
                     65: #include <netinet/ip.h>
                     66:
                     67: #include <dev/pci/if_san_common.h>
                     68: #include <dev/pci/if_san_obsd.h>
                     69:
                     70:
                     71: #ifdef _DEBUG_
                     72: #define        STATIC
                     73: #else
                     74: #define        STATIC          static
                     75: #endif
                     76:
                     77: #define PPP_HEADER_LEN 4               /* should be globaly defined by sppp */
                     78:
                     79:
                     80: static sdla_t *wanpipe_generic_getcard(struct ifnet *);
                     81: static int wanpipe_generic_ioctl(struct ifnet *, u_long, caddr_t);
                     82: static void wanpipe_generic_watchdog(struct ifnet*);
                     83: static void wanpipe_generic_start(struct ifnet *);
                     84:
                     85:
                     86: static char *san_ifname_format = "san%d";
                     87:
                     88:
                     89:
                     90: static sdla_t *
                     91: wanpipe_generic_getcard(struct ifnet *ifp)
                     92: {
                     93:        sdla_t* card;
                     94:
                     95:        if (ifp->if_softc == NULL) {
                     96:                log(LOG_INFO, "%s: Invalid device private structure pointer\n",
                     97:                                ifp->if_xname);
                     98:                return (NULL);
                     99:        }
                    100:        card = ((sdla_t*)((wanpipe_common_t*)ifp->if_softc)->card);
                    101:        if (card == NULL) {
                    102:                log(LOG_INFO, "%s: Invalid Sangoma device card\n",
                    103:                    ifp->if_xname);
                    104:                return (NULL);
                    105:        }
                    106:        return (card);
                    107: }
                    108:
                    109: int
                    110: wanpipe_generic_name(sdla_t *card, char *ifname, int len)
                    111: {
                    112:        static int      ifunit = 0;
                    113:
                    114:        snprintf(ifname, len, san_ifname_format, ifunit++);
                    115:        return (0);
                    116: }
                    117:
                    118: int
                    119: wanpipe_generic_register(sdla_t *card, struct ifnet *ifp, char *ifname)
                    120: {
                    121:        wanpipe_common_t*       common = WAN_IFP_TO_COMMON(ifp);
                    122:
                    123:        if (ifname == NULL || strlen(ifname) > IFNAMSIZ)
                    124:                return (EINVAL);
                    125:        else
                    126:                bcopy(ifname, ifp->if_xname, strlen(ifname));
                    127:
                    128:        IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
                    129:        IFQ_SET_READY(&ifp->if_snd);
                    130:        ifp->if_mtu = PP_MTU;
                    131:        ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
                    132:        common->protocol = IF_PROTO_CISCO;
                    133:
                    134:        ((struct sppp *)ifp)->pp_flags |= PP_CISCO;
                    135:        ((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
                    136:        ((struct sppp *)ifp)->pp_framebytes = 3;
                    137:
                    138:        ifp->if_ioctl = wanpipe_generic_ioctl;  /* Will set from new_if() */
                    139:        ifp->if_start = wanpipe_generic_start;
                    140:        ifp->if_watchdog = wanpipe_generic_watchdog;
                    141:
                    142:        if_attach(ifp);
                    143:        if_alloc_sadl(ifp);
                    144:        sppp_attach(ifp);
                    145:
                    146: #if NBPFILTER > 0
                    147:        bpfattach(&ifp->if_bpf, ifp, DLT_PPP, PPP_HEADER_LEN);
                    148: #endif /* NBPFILTER > 0 */
                    149:
                    150:        return (0);
                    151: }
                    152:
                    153: void
                    154: wanpipe_generic_unregister(struct ifnet *ifp)
                    155: {
                    156:        log(LOG_INFO, "%s: Unregister interface!\n", ifp->if_xname);
                    157:
                    158:        sppp_detach(ifp);
                    159:        if_free_sadl(ifp);
                    160:        if_detach(ifp);
                    161: }
                    162:
                    163: static void
                    164: wanpipe_generic_start(struct ifnet *ifp)
                    165: {
                    166:        sdla_t          *card;
                    167:        struct mbuf     *opkt;
                    168:        int              err = 0;
                    169:
                    170:        if ((card = wanpipe_generic_getcard(ifp)) == NULL)
                    171:                return;
                    172:
                    173:        while (1) {
                    174:                if (sppp_isempty(ifp)) {
                    175:                        /* No more packets in send queue */
                    176:                        break;
                    177:                }
                    178:
                    179:                if ((opkt = sppp_dequeue(ifp)) == NULL) {
                    180:                        /* Should never happened, packet pointer is NULL */
                    181:                        break;
                    182:                }
                    183:                if (card->iface_send == NULL) {
                    184:                        m_freem(opkt);
                    185:                        break;
                    186:                }
                    187:                /* report the packet to BPF if present and attached */
                    188: #if NBPFILTER > 0
                    189:                if (ifp->if_bpf)
                    190:                        bpf_mtap(ifp->if_bpf, opkt, BPF_DIRECTION_OUT);
                    191: #endif /* NBPFILTER > 0 */
                    192:
                    193:                if (wan_mbuf_to_buffer(&opkt)) {
                    194:                        m_freem(opkt);
                    195:                        break;
                    196:                }
                    197:
                    198:                err = card->iface_send(opkt, ifp);
                    199:                if (err)
                    200:                        break;
                    201:        }
                    202: }
                    203:
                    204:
                    205: static int
                    206: wanpipe_generic_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                    207: {
                    208:        struct proc             *p = curproc;
                    209:        struct ifreq            *ifr = (struct ifreq*)data;
                    210:        sdla_t                  *card;
                    211:        wanpipe_common_t*       common = WAN_IFP_TO_COMMON(ifp);
                    212:        struct if_settings      ifsettings;
                    213:        unsigned long           ts_map;
                    214:        int                     err = 0, s;
                    215:
                    216:        if ((card = wanpipe_generic_getcard(ifp)) == NULL)
                    217:                return (EINVAL);
                    218:
                    219:        s = splnet();
                    220:
                    221:        switch (cmd) {
                    222:        case SIOCSIFADDR:
                    223:                // XXX because sppp does an implicit setflags
                    224:                log(LOG_INFO, "%s: Bringing interface up.\n",
                    225:                    ifp->if_xname);
                    226:                if (card->iface_up)
                    227:                        card->iface_up(ifp);
                    228:                wanpipe_generic_start(ifp);
                    229:                err = 1;
                    230:                break;
                    231:
                    232:        case SIOCSIFMEDIA:
                    233:                /* You can't set new media type while card is running */
                    234:                if (card->state != WAN_DISCONNECTED) {
                    235:                        log(LOG_INFO, "%s: Unable to change media type!\n",
                    236:                            ifp->if_xname);
                    237:                        err = EINVAL;
                    238:                } else
                    239:                        err = ifmedia_ioctl(ifp, ifr, &common->ifm, cmd);
                    240:                goto ioctl_out;
                    241:
                    242:        case SIOCGIFMEDIA:
                    243:                err = ifmedia_ioctl(ifp, ifr, &common->ifm, cmd);
                    244:                goto ioctl_out;
                    245:
                    246:        case SIOCSIFTIMESLOT:
                    247:                if ((err = suser(p, p->p_acflag)) != 0)
                    248:                        goto ioctl_out;
                    249:                if (card->state != WAN_DISCONNECTED) {
                    250:                        log(LOG_INFO, "%s: Unable to change timeslot map!\n",
                    251:                            ifp->if_xname);
                    252:                        err = EINVAL;
                    253:                        goto ioctl_out;
                    254:                }
                    255:
                    256:                err = copyin(ifr->ifr_data, &ts_map, sizeof(ts_map));
                    257:                if (err == 0)
                    258:                        sdla_te_settimeslot(card, ts_map);
                    259:
                    260:                goto ioctl_out;
                    261:
                    262:        case SIOCGIFTIMESLOT:
                    263:                ts_map = sdla_te_gettimeslot(card);
                    264:                err = copyout(ifr->ifr_data, &ts_map, sizeof(ts_map));
                    265:                goto ioctl_out;
                    266:
                    267:        case SIOCSIFFLAGS:
                    268:                /*
                    269:                ** If the interface is marked up - enable communications.
                    270:                ** If down - disable communications.  IFF_UP is taken
                    271:                ** care of before entering this function.
                    272:                */
                    273:                err = 1;
                    274:                if ((ifp->if_flags & IFF_UP) == 0) {
                    275:                        if ((ifp->if_flags & IFF_RUNNING) == 0)
                    276:                                break;
                    277:                        /* bring it down */
                    278:                        log(LOG_INFO, "%s: Bringing interface down.\n",
                    279:                            ifp->if_xname);
                    280:                        if (card->iface_down)
                    281:                                card->iface_down(ifp);
                    282:                } else { /* bring it up */
                    283:                        if (ifp->if_flags & IFF_RUNNING)
                    284:                                break;
                    285:                        log(LOG_INFO, "%s: Bringing interface up.\n",
                    286:                            ifp->if_xname);
                    287:                        if (card->iface_up)
                    288:                                card->iface_up(ifp);
                    289:                        wanpipe_generic_start(ifp);
                    290:                }
                    291:                break;
                    292:
                    293:        case SIOC_WANPIPE_DEVICE:
                    294:                err = copyin(ifr->ifr_data, &ifsettings,
                    295:                    sizeof(struct if_settings));
                    296:
                    297:                if (err) {
                    298:                        log(LOG_INFO, "%s: Failed to copy from user space!\n",
                    299:                                                card->devname);
                    300:                        goto ioctl_out;
                    301:                }
                    302:
                    303:                switch (ifsettings.type) {
                    304:                case IF_GET_PROTO:
                    305:                        ifsettings.type = common->protocol;
                    306:                        err = copyout(&ifsettings, ifr->ifr_data,
                    307:                            sizeof(struct if_settings));
                    308:                        if (err)
                    309:                                log(LOG_INFO,
                    310:                                    "%s: Failed to copy to uspace!\n",
                    311:                                    card->devname);
                    312:                        break;
                    313:
                    314:                case IF_PROTO_CISCO:
                    315:                case IF_PROTO_PPP:
                    316:                        if ((err = suser(p, p->p_acflag)) != 0)
                    317:                                goto ioctl_out;
                    318:                        err = wp_lite_set_proto(ifp, (struct ifreq*)data);
                    319:                        break;
                    320:
                    321:                case IF_IFACE_T1:
                    322:                case IF_IFACE_E1:
                    323:                        if ((err = suser(p, p->p_acflag)) != 0)
                    324:                                goto ioctl_out;
                    325:                        err = wp_lite_set_te1_cfg(ifp, (struct ifreq*)data);
                    326:                        break;
                    327:
                    328:                default:
                    329:                        if (card->iface_ioctl)
                    330:                                err = card->iface_ioctl(ifp, cmd,
                    331:                                    (struct ifreq*)data);
                    332:                        break;
                    333:                }
                    334:                goto ioctl_out;
                    335:
                    336:        default:
                    337:                if (card->iface_ioctl) {
                    338:                        /* Argument seqeunce is change for Linux order */
                    339:                        err = card->iface_ioctl(ifp, cmd, (struct ifreq*)data);
                    340:                }
                    341:                break;
                    342:        }
                    343:
                    344:        if (err)
                    345:                err = sppp_ioctl(ifp, cmd, data);
                    346:
                    347: ioctl_out:
                    348:        splx(s);
                    349:        return (err);
                    350: }
                    351:
                    352: static void
                    353: wanpipe_generic_watchdog(struct ifnet *ifp)
                    354: {
                    355:        return;
                    356: }
                    357:
                    358: int
                    359: wanpipe_generic_open(struct ifnet *ifp)
                    360: {
                    361:        return (0);
                    362: }
                    363:
                    364: int
                    365: wanpipe_generic_close(struct ifnet *ifp)
                    366: {
                    367:        return (0);
                    368: }
                    369:
                    370: int
                    371: wanpipe_generic_input(struct ifnet *ifp, struct mbuf *m)
                    372: {
                    373:        sdla_t          *card;
                    374: #if NBPFILTER > 0
                    375: #endif /* NBPFILTER > 0 */
                    376:
                    377:        if ((card = wanpipe_generic_getcard(ifp)) == NULL) {
                    378:                return (-EINVAL);
                    379:        }
                    380:        m->m_pkthdr.rcvif = ifp;
                    381: #if NBPFILTER > 0
                    382:        if (ifp->if_bpf)
                    383:                bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                    384: #endif /* NBPFILTER > 0 */
                    385:        ifp->if_ipackets ++;
                    386:        sppp_input(ifp, m);
                    387:        return (0);
                    388: }
                    389:
                    390: int
                    391: wp_lite_set_proto(struct ifnet *ifp, struct ifreq *ifr)
                    392: {
                    393:        wanpipe_common_t        *common;
                    394:        struct if_settings      *ifsettings;
                    395:        int                      err = 0;
                    396:
                    397:        if ((common = ifp->if_softc) == NULL) {
                    398:                log(LOG_INFO, "%s: Private structure is null!\n",
                    399:                                ifp->if_xname);
                    400:                return (EINVAL);
                    401:        }
                    402:
                    403:        ifsettings = (struct if_settings*) ifr->ifr_data;
                    404:
                    405:        switch (ifsettings->type) {
                    406:        case IF_PROTO_CISCO:
                    407:                if (common->protocol == IF_PROTO_CISCO)
                    408:                        return 0;
                    409:                ((struct sppp *)ifp)->pp_flags |= PP_CISCO;
                    410:                ((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
                    411:                common->protocol = IF_PROTO_CISCO;
                    412:                break;
                    413:        case IF_PROTO_PPP:
                    414:                if (common->protocol == IF_PROTO_PPP)
                    415:                        return 0;
                    416:                ((struct sppp *)ifp)->pp_flags &= ~PP_CISCO;
                    417:                ((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
                    418:                common->protocol = IF_PROTO_PPP;
                    419:                break;
                    420:        }
                    421:
                    422:        err = sppp_ioctl(ifp, SIOCSIFFLAGS, ifr);
                    423:        return (err);
                    424: }
                    425:
                    426: int
                    427: wp_lite_set_te1_cfg(struct ifnet *ifp, struct ifreq *ifr)
                    428: {
                    429:        sdla_t                  *card;
                    430:        struct if_settings      *ifsettings;
                    431:        sdla_te_cfg_t           te_cfg;
                    432:        int                      err = 0;
                    433:
                    434:        if ((card = wanpipe_generic_getcard(ifp)) == NULL)
                    435:                return (EINVAL);
                    436:
                    437:        ifsettings = (struct if_settings*)ifr->ifr_data;
                    438:        err = copyin(ifsettings->ifs_te1, &te_cfg, sizeof(sdla_te_cfg_t));
                    439:
                    440:        if (ifsettings->flags & SANCFG_CLOCK_FLAG)
                    441:                card->fe_te.te_cfg.te_clock = te_cfg.te_clock;
                    442:
                    443:        switch (ifsettings->type) {
                    444:        case IF_IFACE_T1:
                    445:                if (ifsettings->flags & SANCFG_LBO_FLAG)
                    446:                        card->fe_te.te_cfg.lbo = te_cfg.lbo;
                    447:                break;
                    448:        }
                    449:
                    450:        return (err);
                    451: }

CVSweb