linux/net/mac802154/ieee802154_dev.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2007-2012 Siemens AG
   3 *
   4 * Written by:
   5 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
   6 *
   7 * Based on the code from 'linux-zigbee.sourceforge.net' project.
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2
  11 * as published by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License along
  19 * with this program; if not, write to the Free Software Foundation, Inc.,
  20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21 */
  22
  23#include <linux/kernel.h>
  24#include <linux/module.h>
  25#include <linux/netdevice.h>
  26
  27#include <net/netlink.h>
  28#include <linux/nl802154.h>
  29#include <net/mac802154.h>
  30#include <net/route.h>
  31#include <net/wpan-phy.h>
  32
  33#include "mac802154.h"
  34
  35int mac802154_slave_open(struct net_device *dev)
  36{
  37        struct mac802154_sub_if_data *priv = netdev_priv(dev);
  38        struct mac802154_priv *ipriv = priv->hw;
  39        int res = 0;
  40
  41        if (ipriv->open_count++ == 0) {
  42                res = ipriv->ops->start(&ipriv->hw);
  43                WARN_ON(res);
  44                if (res)
  45                        goto err;
  46        }
  47
  48        if (ipriv->ops->ieee_addr) {
  49                res = ipriv->ops->ieee_addr(&ipriv->hw, dev->dev_addr);
  50                WARN_ON(res);
  51                if (res)
  52                        goto err;
  53                mac802154_dev_set_ieee_addr(dev);
  54        }
  55
  56        netif_start_queue(dev);
  57        return 0;
  58err:
  59        priv->hw->open_count--;
  60
  61        return res;
  62}
  63
  64int mac802154_slave_close(struct net_device *dev)
  65{
  66        struct mac802154_sub_if_data *priv = netdev_priv(dev);
  67        struct mac802154_priv *ipriv = priv->hw;
  68
  69        netif_stop_queue(dev);
  70
  71        if (!--ipriv->open_count)
  72                ipriv->ops->stop(&ipriv->hw);
  73
  74        return 0;
  75}
  76
  77static int
  78mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev)
  79{
  80        struct mac802154_sub_if_data *priv;
  81        struct mac802154_priv *ipriv;
  82        int err;
  83
  84        ipriv = wpan_phy_priv(phy);
  85
  86        priv = netdev_priv(dev);
  87        priv->dev = dev;
  88        priv->hw = ipriv;
  89
  90        dev->needed_headroom = ipriv->hw.extra_tx_headroom;
  91
  92        SET_NETDEV_DEV(dev, &ipriv->phy->dev);
  93
  94        mutex_lock(&ipriv->slaves_mtx);
  95        if (!ipriv->running) {
  96                mutex_unlock(&ipriv->slaves_mtx);
  97                return -ENODEV;
  98        }
  99        mutex_unlock(&ipriv->slaves_mtx);
 100
 101        err = register_netdev(dev);
 102        if (err < 0)
 103                return err;
 104
 105        rtnl_lock();
 106        mutex_lock(&ipriv->slaves_mtx);
 107        list_add_tail_rcu(&priv->list, &ipriv->slaves);
 108        mutex_unlock(&ipriv->slaves_mtx);
 109        rtnl_unlock();
 110
 111        return 0;
 112}
 113
 114static void
 115mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev)
 116{
 117        struct mac802154_sub_if_data *sdata;
 118        ASSERT_RTNL();
 119
 120        sdata = netdev_priv(dev);
 121
 122        BUG_ON(sdata->hw->phy != phy);
 123
 124        mutex_lock(&sdata->hw->slaves_mtx);
 125        list_del_rcu(&sdata->list);
 126        mutex_unlock(&sdata->hw->slaves_mtx);
 127
 128        synchronize_rcu();
 129        unregister_netdevice(sdata->dev);
 130}
 131
 132static struct net_device *
 133mac802154_add_iface(struct wpan_phy *phy, const char *name, int type)
 134{
 135        struct net_device *dev;
 136        int err = -ENOMEM;
 137
 138        switch (type) {
 139        case IEEE802154_DEV_MONITOR:
 140                dev = alloc_netdev(sizeof(struct mac802154_sub_if_data),
 141                                   name, mac802154_monitor_setup);
 142                break;
 143        case IEEE802154_DEV_WPAN:
 144                dev = alloc_netdev(sizeof(struct mac802154_sub_if_data),
 145                                   name, mac802154_wpan_setup);
 146                break;
 147        default:
 148                dev = NULL;
 149                err = -EINVAL;
 150                break;
 151        }
 152        if (!dev)
 153                goto err;
 154
 155        err = mac802154_netdev_register(phy, dev);
 156        if (err)
 157                goto err_free;
 158
 159        dev_hold(dev); /* we return an incremented device refcount */
 160        return dev;
 161
 162err_free:
 163        free_netdev(dev);
 164err:
 165        return ERR_PTR(err);
 166}
 167
 168struct ieee802154_dev *
 169ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops)
 170{
 171        struct wpan_phy *phy;
 172        struct mac802154_priv *priv;
 173        size_t priv_size;
 174
 175        if (!ops || !ops->xmit || !ops->ed || !ops->start ||
 176            !ops->stop || !ops->set_channel) {
 177                printk(KERN_ERR
 178                       "undefined IEEE802.15.4 device operations\n");
 179                return NULL;
 180        }
 181
 182        /* Ensure 32-byte alignment of our private data and hw private data.
 183         * We use the wpan_phy priv data for both our mac802154_priv and for
 184         * the driver's private data
 185         *
 186         * in memory it'll be like this:
 187         *
 188         * +-----------------------+
 189         * | struct wpan_phy       |
 190         * +-----------------------+
 191         * | struct mac802154_priv |
 192         * +-----------------------+
 193         * | driver's private data |
 194         * +-----------------------+
 195         *
 196         * Due to ieee802154 layer isn't aware of driver and MAC structures,
 197         * so lets allign them here.
 198         */
 199
 200        priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len;
 201
 202        phy = wpan_phy_alloc(priv_size);
 203        if (!phy) {
 204                printk(KERN_ERR
 205                       "failure to allocate master IEEE802.15.4 device\n");
 206                return NULL;
 207        }
 208
 209        priv = wpan_phy_priv(phy);
 210        priv->hw.phy = priv->phy = phy;
 211        priv->hw.priv = (char *)edata" class="sref">mac802154_sub_if_y2->a>( 140                          h0AI+code=dev" cl40          h0AI+code=de+code=dev" cl40    line" name="L163"> 163  2net/mac802154/ieee802154_dev.c#L112" id=21href="+code=phy" class="srefINIT_LIST_HEAD0          INIT_LIST_HEADcode=+code=slaves_mtx" class="sref">slaves_mtx);
list_add_tail_rcu(&
slaves_mtx);
 126        wpan_phy *  74        return 0;
net_device<2a> *<21L56">  56       +code=slaves_mtx" class="sref">slaves_mtx);
  67        struct  117 2     2struct#L206" id="L206" class="line" name="L206"> 2ef">sdata2/a>;
 208
 168struct  112        2120         169 168struct  166}
  67size_t netdev_priv2/a>(<2 href=_phy_alloc(sdata<2a>-&g22">phy = < 171        struct wpan_phy *phyto"+cod"L208"> 208
ipriv->phy 173        mutex_2ock(&sdata-&g">dev);
priv"srefemptlcode=+code=slaves_mtx" class="sref">slaves_mtx);
list_ipriv" class="sref">ipriv->  74        return 0;
mutex_un2ock(&mutex_lock(&dev;
 201
 210        ipriv->hw->NULL;
 210   a" clade 17o2code=+code=slaves_mtx" class="sref">slaves_mtx);
 126        unregister_netdevice(sdata-2gt; 208
 168struct 
 168struct  166}
wpan_phy *phy, const char *name, i2t typewpan_phy *phyto"+cod"L208"> 208
err_free:
 135        struct r" id="L201" clasrchynet_device *dev;
 136        int err = -2a hre23 priv->hy 136        int  137
 148         create_singlet/a>adaworkw;
 208
 201
 210        err_free:
priv->hy = adev.c#L156" id="L156ou="L70" class="linutdev" class="sref">dev;
 141mac822154_24172        struct  201
 210        hwpriv->phy = err_free:
 173         = sdata-&gref=54_dev.c#L210" id="L210" class="line" name="L210"> 210         13c struct  132static struct err_free:
sdata-&gref=54_dev.c#L210" id="L210" class="line" name="L210"> 210        err_free:
m2c802124line" name="L136"> 136        int  201
 210        ipriv->mac802154_netdev_r" id="L201" clasrchyregister_netdev( 149err_free:
), #L150" id2"L150" class="line" name2"L150253" id="L193" class="line" n0f">err;
        }
    line" name="L163"> 163  2ass="sref2>dev)
phy);
slaves_mtx);
 126         153               2goto 2a href="+code=err" class="sreass="sref">slaves_mtx);
);
err_free:
sdata-&ga>(&sdata->slaves_mtx);
 126        dev);
 136        int ipriv->s2> 1572               goto 2ev_hold(
 160        r2turn 2a href="+code=dev" clou=_wq"L70" class="linut_wq" idfree_netdev" class="sref">free_netdev(<2ss="line"2name="L161"> 161
"L201"> 201
;
 163free_netdev(<2sme="L1532de=dev" class="sref">dev2/a>);2();
 165        return ERR_PTR<2a>( 208
 168struct )2154/ieee802154_dev.c#L162" id=26e=NULL" class="sref">NULL;
 167 169 168struct  166}
2riv_data_len, struct ieee802154_ops<2a> *<2 href="+code=ops" class="sref">opswpan_phy *phyto"+cod"L208"> 208
err_free:
 171        struct  116{
    line" name="L163"> 163  2e802154_d2v.c#L173" id="L173" clas2="lin27href="+code=phy" class="srefflushaworkw;
 201
;
size_t "L201"> 201
;
ops-&g2;  74        return 0;
o2s->mutex_lock(&err;
NULL;
);
slaves_mtx);
 126        priv = wpan_pf="+code=slaves_mtx" class="sref"mac  struct           MACk" clasDEVICE_STOPPEDhy();
sdata->slaves_mtx);
 126        ;
"L201"> 201
 116{
slaves_mtx);
list,s="line" name="Lt/mac802154/ieee802154_dev.cn_phy_alloc(phy);
 123
 124         204     eee802154_dev.c"srefd"L176" class="lin"srefd"Lieee802154_dev.c#L123" id="L123" class="line" name="L123"> 123
 2    * the2driver's private dat2 205     priv" class="sra>(&sdata-> 123
 124        o2a href="net/mac802154/ie2e802128line" name="L136"> 136        int  128        synchronize_rcu();
 129  2        *2/span>
 165        return 
ipriv->s2--------+2/span>
        struct  201
 210        ipriv-> 165        return  208
 168struct ipriv->  74        return 0;
KERN_ERR
KERN_ERR

The original LXR softe="L1bycommeRN_ERR
LXR 7" iunit   

1xc.gn ux.no kindly hosieeebycRN_ERR
<5.