mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-14 16:44:29 +08:00
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>
This commit is contained in:
parent
6fa2cffe8c
commit
e369dc8f1a
@ -28,16 +28,18 @@
|
|||||||
#include <net/cfg802154.h>
|
#include <net/cfg802154.h>
|
||||||
|
|
||||||
static int numlbs = 2;
|
static int numlbs = 2;
|
||||||
static DEFINE_RWLOCK(fakelb_lock);
|
|
||||||
static LIST_HEAD(fakelb_phys);
|
static LIST_HEAD(fakelb_phys);
|
||||||
|
static DEFINE_SPINLOCK(fakelb_phys_lock);
|
||||||
|
|
||||||
|
static LIST_HEAD(fakelb_ifup_phys);
|
||||||
|
static DEFINE_RWLOCK(fakelb_ifup_phys_lock);
|
||||||
|
|
||||||
struct fakelb_phy {
|
struct fakelb_phy {
|
||||||
struct ieee802154_hw *hw;
|
struct ieee802154_hw *hw;
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct list_head list_ifup;
|
||||||
spinlock_t lock;
|
|
||||||
bool working;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -62,13 +64,9 @@ fakelb_hw_deliver(struct fakelb_phy *phy, struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
struct sk_buff *newskb;
|
struct sk_buff *newskb;
|
||||||
|
|
||||||
spin_lock(&phy->lock);
|
newskb = pskb_copy(skb, GFP_ATOMIC);
|
||||||
if (phy->working) {
|
if (newskb)
|
||||||
newskb = pskb_copy(skb, GFP_ATOMIC);
|
ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
|
||||||
if (newskb)
|
|
||||||
ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
|
|
||||||
}
|
|
||||||
spin_unlock(&phy->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -77,8 +75,8 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
|
|||||||
struct fakelb_phy *current_phy = hw->priv;
|
struct fakelb_phy *current_phy = hw->priv;
|
||||||
struct fakelb_phy *phy;
|
struct fakelb_phy *phy;
|
||||||
|
|
||||||
read_lock_bh(&fakelb_lock);
|
read_lock_bh(&fakelb_ifup_phys_lock);
|
||||||
list_for_each_entry(phy, &fakelb_phys, list) {
|
list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) {
|
||||||
if (current_phy == phy)
|
if (current_phy == phy)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -86,7 +84,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
|
|||||||
current_phy->hw->phy->current_channel)
|
current_phy->hw->phy->current_channel)
|
||||||
fakelb_hw_deliver(phy, skb);
|
fakelb_hw_deliver(phy, skb);
|
||||||
}
|
}
|
||||||
read_unlock_bh(&fakelb_lock);
|
read_unlock_bh(&fakelb_ifup_phys_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -94,25 +92,21 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
|
|||||||
static int
|
static int
|
||||||
fakelb_hw_start(struct ieee802154_hw *hw) {
|
fakelb_hw_start(struct ieee802154_hw *hw) {
|
||||||
struct fakelb_phy *phy = hw->priv;
|
struct fakelb_phy *phy = hw->priv;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
spin_lock(&phy->lock);
|
write_lock_bh(&fakelb_ifup_phys_lock);
|
||||||
if (phy->working)
|
list_add(&phy->list_ifup, &fakelb_ifup_phys);
|
||||||
ret = -EBUSY;
|
write_unlock_bh(&fakelb_ifup_phys_lock);
|
||||||
else
|
|
||||||
phy->working = 1;
|
|
||||||
spin_unlock(&phy->lock);
|
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fakelb_hw_stop(struct ieee802154_hw *hw) {
|
fakelb_hw_stop(struct ieee802154_hw *hw) {
|
||||||
struct fakelb_phy *phy = hw->priv;
|
struct fakelb_phy *phy = hw->priv;
|
||||||
|
|
||||||
spin_lock(&phy->lock);
|
write_lock_bh(&fakelb_ifup_phys_lock);
|
||||||
phy->working = 0;
|
list_del(&phy->list_ifup);
|
||||||
spin_unlock(&phy->lock);
|
write_unlock_bh(&fakelb_ifup_phys_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ieee802154_ops fakelb_ops = {
|
static const struct ieee802154_ops fakelb_ops = {
|
||||||
@ -172,17 +166,15 @@ static int fakelb_add_one(struct device *dev)
|
|||||||
/* 950 MHz GFSK 802.15.4d-2009 */
|
/* 950 MHz GFSK 802.15.4d-2009 */
|
||||||
hw->phy->supported.channels[6] |= 0x3ffc00;
|
hw->phy->supported.channels[6] |= 0x3ffc00;
|
||||||
|
|
||||||
spin_lock_init(&phy->lock);
|
|
||||||
|
|
||||||
hw->parent = dev;
|
hw->parent = dev;
|
||||||
|
|
||||||
err = ieee802154_register_hw(hw);
|
err = ieee802154_register_hw(hw);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_reg;
|
goto err_reg;
|
||||||
|
|
||||||
write_lock_bh(&fakelb_lock);
|
spin_lock(&fakelb_phys_lock);
|
||||||
list_add_tail(&phy->list, &fakelb_phys);
|
list_add_tail(&phy->list, &fakelb_phys);
|
||||||
write_unlock_bh(&fakelb_lock);
|
spin_unlock(&fakelb_phys_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -215,10 +207,10 @@ static int fakelb_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_slave:
|
err_slave:
|
||||||
write_lock_bh(&fakelb_lock);
|
spin_lock(&fakelb_phys_lock);
|
||||||
list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
|
list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
|
||||||
fakelb_del(phy);
|
fakelb_del(phy);
|
||||||
write_unlock_bh(&fakelb_lock);
|
spin_unlock(&fakelb_phys_lock);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,10 +218,10 @@ static int fakelb_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct fakelb_phy *phy, *temp;
|
struct fakelb_phy *phy, *temp;
|
||||||
|
|
||||||
write_lock_bh(&fakelb_lock);
|
spin_lock(&fakelb_phys_lock);
|
||||||
list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
|
list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
|
||||||
fakelb_del(phy);
|
fakelb_del(phy);
|
||||||
write_unlock_bh(&fakelb_lock);
|
spin_unlock(&fakelb_phys_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user