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 ---