aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ieee802154
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2015-05-17 15:45:05 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-05-19 05:44:46 -0400
commite369dc8f1aa95cd490e1ab75043dcf50d2190453 (patch)
tree4e6693168f9ffa162fe1c4566750ef20ac9f7962 /drivers/net/ieee802154
parent6fa2cffe8cf937fc10be362a2dcac8a5965f618e (diff)
fakelb: introduce fakelb ifup phys list
This patch introduce a fakelb ifup phys list, which stores all registered phys which are in an operated mode. This will reduce the iterations of non-operated phys while transmit frames. There exists two locks now, one rwlock for the operated interfaces and the spinlock for protecting the list for all registered virtual phys. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r--drivers/net/ieee802154/fakelb.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index e1c0195c18aa..83957de47243 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -28,16 +28,18 @@
28#include <net/cfg802154.h> 28#include <net/cfg802154.h>
29 29
30static int numlbs = 2; 30static int numlbs = 2;
31static DEFINE_RWLOCK(fakelb_lock); 31
32static LIST_HEAD(fakelb_phys); 32static LIST_HEAD(fakelb_phys);
33static DEFINE_SPINLOCK(fakelb_phys_lock);
34
35static LIST_HEAD(fakelb_ifup_phys);
36static DEFINE_RWLOCK(fakelb_ifup_phys_lock);
33 37
34struct fakelb_phy { 38struct fakelb_phy {
35 struct ieee802154_hw *hw; 39 struct ieee802154_hw *hw;
36 40
37 struct list_head list; 41 struct list_head list;
38 42 struct list_head list_ifup;
39 spinlock_t lock;
40 bool working;
41}; 43};
42 44
43static int 45static int
@@ -62,13 +64,9 @@ fakelb_hw_deliver(struct fakelb_phy *phy, struct sk_buff *skb)
62{ 64{
63 struct sk_buff *newskb; 65 struct sk_buff *newskb;
64 66
65 spin_lock(&phy->lock); 67 newskb = pskb_copy(skb, GFP_ATOMIC);
66 if (phy->working) { 68 if (newskb)
67 newskb = pskb_copy(skb, GFP_ATOMIC); 69 ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
68 if (newskb)
69 ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
70 }
71 spin_unlock(&phy->lock);
72} 70}
73 71
74static int 72static int
@@ -77,8 +75,8 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
77 struct fakelb_phy *current_phy = hw->priv; 75 struct fakelb_phy *current_phy = hw->priv;
78 struct fakelb_phy *phy; 76 struct fakelb_phy *phy;
79 77
80 read_lock_bh(&fakelb_lock); 78 read_lock_bh(&fakelb_ifup_phys_lock);
81 list_for_each_entry(phy, &fakelb_phys, list) { 79 list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) {
82 if (current_phy == phy) 80 if (current_phy == phy)
83 continue; 81 continue;
84 82
@@ -86,7 +84,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
86 current_phy->hw->phy->current_channel) 84 current_phy->hw->phy->current_channel)
87 fakelb_hw_deliver(phy, skb); 85 fakelb_hw_deliver(phy, skb);
88 } 86 }
89 read_unlock_bh(&fakelb_lock); 87 read_unlock_bh(&fakelb_ifup_phys_lock);
90 88
91 return 0; 89 return 0;
92} 90}
@@ -94,25 +92,21 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
94static int 92static int
95fakelb_hw_start(struct ieee802154_hw *hw) { 93fakelb_hw_start(struct ieee802154_hw *hw) {
96 struct fakelb_phy *phy = hw->priv; 94 struct fakelb_phy *phy = hw->priv;
97 int ret = 0;
98 95
99 spin_lock(&phy->lock); 96 write_lock_bh(&fakelb_ifup_phys_lock);
100 if (phy->working) 97 list_add(&phy->list_ifup, &fakelb_ifup_phys);
101 ret = -EBUSY; 98 write_unlock_bh(&fakelb_ifup_phys_lock);
102 else
103 phy->working = 1;
104 spin_unlock(&phy->lock);
105 99
106 return ret; 100 return 0;
107} 101}
108 102
109static void 103static void
110fakelb_hw_stop(struct ieee802154_hw *hw) { 104fakelb_hw_stop(struct ieee802154_hw *hw) {
111 struct fakelb_phy *phy = hw->priv; 105 struct fakelb_phy *phy = hw->priv;
112 106
113 spin_lock(&phy->lock); 107 write_lock_bh(&fakelb_ifup_phys_lock);
114 phy->working = 0; 108 list_del(&phy->list_ifup);
115 spin_unlock(&phy->lock); 109 write_unlock_bh(&fakelb_ifup_phys_lock);
116} 110}
117 111
118static const struct ieee802154_ops fakelb_ops = { 112static const struct ieee802154_ops fakelb_ops = {
@@ -172,17 +166,15 @@ static int fakelb_add_one(struct device *dev)
172 /* 950 MHz GFSK 802.15.4d-2009 */ 166 /* 950 MHz GFSK 802.15.4d-2009 */
173 hw->phy->supported.channels[6] |= 0x3ffc00; 167 hw->phy->supported.channels[6] |= 0x3ffc00;
174 168
175 spin_lock_init(&phy->lock);
176
177 hw->parent = dev; 169 hw->parent = dev;
178 170
179 err = ieee802154_register_hw(hw); 171 err = ieee802154_register_hw(hw);
180 if (err) 172 if (err)
181 goto err_reg; 173 goto err_reg;
182 174
183 write_lock_bh(&fakelb_lock); 175 spin_lock(&fakelb_phys_lock);
184 list_add_tail(&phy->list, &fakelb_phys); 176 list_add_tail(&phy->list, &fakelb_phys);
185 write_unlock_bh(&fakelb_lock); 177 spin_unlock(&fakelb_phys_lock);
186 178
187 return 0; 179 return 0;
188 180
@@ -215,10 +207,10 @@ static int fakelb_probe(struct platform_device *pdev)
215 return 0; 207 return 0;
216 208
217err_slave: 209err_slave:
218 write_lock_bh(&fakelb_lock); 210 spin_lock(&fakelb_phys_lock);
219 list_for_each_entry_safe(phy, tmp, &fakelb_phys, list) 211 list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
220 fakelb_del(phy); 212 fakelb_del(phy);
221 write_unlock_bh(&fakelb_lock); 213 spin_unlock(&fakelb_phys_lock);
222 return err; 214 return err;
223} 215}
224 216
@@ -226,10 +218,10 @@ static int fakelb_remove(struct platform_device *pdev)
226{ 218{
227 struct fakelb_phy *phy, *temp; 219 struct fakelb_phy *phy, *temp;
228 220
229 write_lock_bh(&fakelb_lock); 221 spin_lock(&fakelb_phys_lock);
230 list_for_each_entry_safe(phy, temp, &fakelb_phys, list) 222 list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
231 fakelb_del(phy); 223 fakelb_del(phy);
232 write_unlock_bh(&fakelb_lock); 224 spin_unlock(&fakelb_phys_lock);
233 return 0; 225 return 0;
234} 226}
235 227