fakelb.c (5ad60d36993596f7b3b958500f9c66c5338cd855) | fakelb.c (5a50439775853a8d565115edb63a5ab4bb780479) |
---|---|
1/* 2 * Loopback IEEE 802.15.4 interface 3 * 4 * Copyright 2007-2012 Siemens AG 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 8 * as published by the Free Software Foundation. --- 16 unchanged lines hidden (view full) --- 25#include <linux/device.h> 26#include <linux/spinlock.h> 27#include <net/mac802154.h> 28#include <net/cfg802154.h> 29 30static int numlbs = 1; 31 32struct fakelb_dev_priv { | 1/* 2 * Loopback IEEE 802.15.4 interface 3 * 4 * Copyright 2007-2012 Siemens AG 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 8 * as published by the Free Software Foundation. --- 16 unchanged lines hidden (view full) --- 25#include <linux/device.h> 26#include <linux/spinlock.h> 27#include <net/mac802154.h> 28#include <net/cfg802154.h> 29 30static int numlbs = 1; 31 32struct fakelb_dev_priv { |
33 struct ieee802154_dev *dev; | 33 struct ieee802154_hw *hw; |
34 35 struct list_head list; 36 struct fakelb_priv *fake; 37 38 spinlock_t lock; 39 bool working; 40}; 41 42struct fakelb_priv { 43 struct list_head list; 44 rwlock_t lock; 45}; 46 47static int | 34 35 struct list_head list; 36 struct fakelb_priv *fake; 37 38 spinlock_t lock; 39 bool working; 40}; 41 42struct fakelb_priv { 43 struct list_head list; 44 rwlock_t lock; 45}; 46 47static int |
48fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) | 48fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level) |
49{ 50 might_sleep(); 51 BUG_ON(!level); 52 *level = 0xbe; 53 54 return 0; 55} 56 57static int | 49{ 50 might_sleep(); 51 BUG_ON(!level); 52 *level = 0xbe; 53 54 return 0; 55} 56 57static int |
58fakelb_hw_channel(struct ieee802154_dev *dev, int page, int channel) | 58fakelb_hw_channel(struct ieee802154_hw *hw, int page, int channel) |
59{ 60 pr_debug("set channel to %d\n", channel); 61 62 might_sleep(); | 59{ 60 pr_debug("set channel to %d\n", channel); 61 62 might_sleep(); |
63 dev->phy->current_page = page; 64 dev->phy->current_channel = channel; | 63 hw->phy->current_page = page; 64 hw->phy->current_channel = channel; |
65 66 return 0; 67} 68 69static void 70fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) 71{ 72 struct sk_buff *newskb; 73 74 spin_lock(&priv->lock); 75 if (priv->working) { 76 newskb = pskb_copy(skb, GFP_ATOMIC); | 65 66 return 0; 67} 68 69static void 70fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) 71{ 72 struct sk_buff *newskb; 73 74 spin_lock(&priv->lock); 75 if (priv->working) { 76 newskb = pskb_copy(skb, GFP_ATOMIC); |
77 ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc); | 77 ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc); |
78 } 79 spin_unlock(&priv->lock); 80} 81 82static int | 78 } 79 spin_unlock(&priv->lock); 80} 81 82static int |
83fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) | 83fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) |
84{ | 84{ |
85 struct fakelb_dev_priv *priv = dev->priv; | 85 struct fakelb_dev_priv *priv = hw->priv; |
86 struct fakelb_priv *fake = priv->fake; 87 88 might_sleep(); 89 90 read_lock_bh(&fake->lock); 91 if (priv->list.next == priv->list.prev) { 92 /* we are the only one device */ 93 fakelb_hw_deliver(priv, skb); 94 } else { 95 struct fakelb_dev_priv *dp; 96 list_for_each_entry(dp, &priv->fake->list, list) { 97 if (dp != priv && | 86 struct fakelb_priv *fake = priv->fake; 87 88 might_sleep(); 89 90 read_lock_bh(&fake->lock); 91 if (priv->list.next == priv->list.prev) { 92 /* we are the only one device */ 93 fakelb_hw_deliver(priv, skb); 94 } else { 95 struct fakelb_dev_priv *dp; 96 list_for_each_entry(dp, &priv->fake->list, list) { 97 if (dp != priv && |
98 (dp->dev->phy->current_channel == 99 priv->dev->phy->current_channel)) | 98 (dp->hw->phy->current_channel == 99 priv->hw->phy->current_channel)) |
100 fakelb_hw_deliver(dp, skb); 101 } 102 } 103 read_unlock_bh(&fake->lock); 104 105 return 0; 106} 107 108static int | 100 fakelb_hw_deliver(dp, skb); 101 } 102 } 103 read_unlock_bh(&fake->lock); 104 105 return 0; 106} 107 108static int |
109fakelb_hw_start(struct ieee802154_dev *dev) { 110 struct fakelb_dev_priv *priv = dev->priv; | 109fakelb_hw_start(struct ieee802154_hw *hw) { 110 struct fakelb_dev_priv *priv = hw->priv; |
111 int ret = 0; 112 113 spin_lock(&priv->lock); 114 if (priv->working) 115 ret = -EBUSY; 116 else 117 priv->working = 1; 118 spin_unlock(&priv->lock); 119 120 return ret; 121} 122 123static void | 111 int ret = 0; 112 113 spin_lock(&priv->lock); 114 if (priv->working) 115 ret = -EBUSY; 116 else 117 priv->working = 1; 118 spin_unlock(&priv->lock); 119 120 return ret; 121} 122 123static void |
124fakelb_hw_stop(struct ieee802154_dev *dev) { 125 struct fakelb_dev_priv *priv = dev->priv; | 124fakelb_hw_stop(struct ieee802154_hw *hw) { 125 struct fakelb_dev_priv *priv = hw->priv; |
126 127 spin_lock(&priv->lock); 128 priv->working = 0; 129 spin_unlock(&priv->lock); 130} 131 132static struct ieee802154_ops fakelb_ops = { 133 .owner = THIS_MODULE, --- 7 unchanged lines hidden (view full) --- 141/* Number of dummy devices to be set up by this module. */ 142module_param(numlbs, int, 0); 143MODULE_PARM_DESC(numlbs, " number of pseudo devices"); 144 145static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) 146{ 147 struct fakelb_dev_priv *priv; 148 int err; | 126 127 spin_lock(&priv->lock); 128 priv->working = 0; 129 spin_unlock(&priv->lock); 130} 131 132static struct ieee802154_ops fakelb_ops = { 133 .owner = THIS_MODULE, --- 7 unchanged lines hidden (view full) --- 141/* Number of dummy devices to be set up by this module. */ 142module_param(numlbs, int, 0); 143MODULE_PARM_DESC(numlbs, " number of pseudo devices"); 144 145static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) 146{ 147 struct fakelb_dev_priv *priv; 148 int err; |
149 struct ieee802154_dev *ieee; | 149 struct ieee802154_hw *hw; |
150 | 150 |
151 ieee = ieee802154_alloc_device(sizeof(*priv), &fakelb_ops); 152 if (!ieee) | 151 hw = ieee802154_alloc_hw(sizeof(*priv), &fakelb_ops); 152 if (!hw) |
153 return -ENOMEM; 154 | 153 return -ENOMEM; 154 |
155 priv = ieee->priv; 156 priv->dev = ieee; | 155 priv = hw->priv; 156 priv->hw = hw; |
157 158 /* 868 MHz BPSK 802.15.4-2003 */ | 157 158 /* 868 MHz BPSK 802.15.4-2003 */ |
159 ieee->phy->channels_supported[0] |= 1; | 159 hw->phy->channels_supported[0] |= 1; |
160 /* 915 MHz BPSK 802.15.4-2003 */ | 160 /* 915 MHz BPSK 802.15.4-2003 */ |
161 ieee->phy->channels_supported[0] |= 0x7fe; | 161 hw->phy->channels_supported[0] |= 0x7fe; |
162 /* 2.4 GHz O-QPSK 802.15.4-2003 */ | 162 /* 2.4 GHz O-QPSK 802.15.4-2003 */ |
163 ieee->phy->channels_supported[0] |= 0x7FFF800; | 163 hw->phy->channels_supported[0] |= 0x7FFF800; |
164 /* 868 MHz ASK 802.15.4-2006 */ | 164 /* 868 MHz ASK 802.15.4-2006 */ |
165 ieee->phy->channels_supported[1] |= 1; | 165 hw->phy->channels_supported[1] |= 1; |
166 /* 915 MHz ASK 802.15.4-2006 */ | 166 /* 915 MHz ASK 802.15.4-2006 */ |
167 ieee->phy->channels_supported[1] |= 0x7fe; | 167 hw->phy->channels_supported[1] |= 0x7fe; |
168 /* 868 MHz O-QPSK 802.15.4-2006 */ | 168 /* 868 MHz O-QPSK 802.15.4-2006 */ |
169 ieee->phy->channels_supported[2] |= 1; | 169 hw->phy->channels_supported[2] |= 1; |
170 /* 915 MHz O-QPSK 802.15.4-2006 */ | 170 /* 915 MHz O-QPSK 802.15.4-2006 */ |
171 ieee->phy->channels_supported[2] |= 0x7fe; | 171 hw->phy->channels_supported[2] |= 0x7fe; |
172 /* 2.4 GHz CSS 802.15.4a-2007 */ | 172 /* 2.4 GHz CSS 802.15.4a-2007 */ |
173 ieee->phy->channels_supported[3] |= 0x3fff; | 173 hw->phy->channels_supported[3] |= 0x3fff; |
174 /* UWB Sub-gigahertz 802.15.4a-2007 */ | 174 /* UWB Sub-gigahertz 802.15.4a-2007 */ |
175 ieee->phy->channels_supported[4] |= 1; | 175 hw->phy->channels_supported[4] |= 1; |
176 /* UWB Low band 802.15.4a-2007 */ | 176 /* UWB Low band 802.15.4a-2007 */ |
177 ieee->phy->channels_supported[4] |= 0x1e; | 177 hw->phy->channels_supported[4] |= 0x1e; |
178 /* UWB High band 802.15.4a-2007 */ | 178 /* UWB High band 802.15.4a-2007 */ |
179 ieee->phy->channels_supported[4] |= 0xffe0; | 179 hw->phy->channels_supported[4] |= 0xffe0; |
180 /* 750 MHz O-QPSK 802.15.4c-2009 */ | 180 /* 750 MHz O-QPSK 802.15.4c-2009 */ |
181 ieee->phy->channels_supported[5] |= 0xf; | 181 hw->phy->channels_supported[5] |= 0xf; |
182 /* 750 MHz MPSK 802.15.4c-2009 */ | 182 /* 750 MHz MPSK 802.15.4c-2009 */ |
183 ieee->phy->channels_supported[5] |= 0xf0; | 183 hw->phy->channels_supported[5] |= 0xf0; |
184 /* 950 MHz BPSK 802.15.4d-2009 */ | 184 /* 950 MHz BPSK 802.15.4d-2009 */ |
185 ieee->phy->channels_supported[6] |= 0x3ff; | 185 hw->phy->channels_supported[6] |= 0x3ff; |
186 /* 950 MHz GFSK 802.15.4d-2009 */ | 186 /* 950 MHz GFSK 802.15.4d-2009 */ |
187 ieee->phy->channels_supported[6] |= 0x3ffc00; | 187 hw->phy->channels_supported[6] |= 0x3ffc00; |
188 189 INIT_LIST_HEAD(&priv->list); 190 priv->fake = fake; 191 192 spin_lock_init(&priv->lock); 193 | 188 189 INIT_LIST_HEAD(&priv->list); 190 priv->fake = fake; 191 192 spin_lock_init(&priv->lock); 193 |
194 ieee->parent = dev; | 194 hw->parent = dev; |
195 | 195 |
196 err = ieee802154_register_device(ieee); | 196 err = ieee802154_register_hw(hw); |
197 if (err) 198 goto err_reg; 199 200 write_lock_bh(&fake->lock); 201 list_add_tail(&priv->list, &fake->list); 202 write_unlock_bh(&fake->lock); 203 204 return 0; 205 206err_reg: | 197 if (err) 198 goto err_reg; 199 200 write_lock_bh(&fake->lock); 201 list_add_tail(&priv->list, &fake->list); 202 write_unlock_bh(&fake->lock); 203 204 return 0; 205 206err_reg: |
207 ieee802154_free_device(priv->dev); | 207 ieee802154_free_hw(priv->hw); |
208 return err; 209} 210 211static void fakelb_del(struct fakelb_dev_priv *priv) 212{ 213 write_lock_bh(&priv->fake->lock); 214 list_del(&priv->list); 215 write_unlock_bh(&priv->fake->lock); 216 | 208 return err; 209} 210 211static void fakelb_del(struct fakelb_dev_priv *priv) 212{ 213 write_lock_bh(&priv->fake->lock); 214 list_del(&priv->list); 215 write_unlock_bh(&priv->fake->lock); 216 |
217 ieee802154_unregister_device(priv->dev); 218 ieee802154_free_device(priv->dev); | 217 ieee802154_unregister_hw(priv->hw); 218 ieee802154_free_hw(priv->hw); |
219} 220 221static int fakelb_probe(struct platform_device *pdev) 222{ 223 struct fakelb_priv *priv; 224 struct fakelb_dev_priv *dp; 225 int err = -ENOMEM; 226 int i; --- 64 unchanged lines hidden --- | 219} 220 221static int fakelb_probe(struct platform_device *pdev) 222{ 223 struct fakelb_priv *priv; 224 struct fakelb_dev_priv *dp; 225 int err = -ENOMEM; 226 int i; --- 64 unchanged lines hidden --- |