2019-05-27 09:55:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
/*
2014-10-26 11:37:05 +03:00
*
* Authors :
* Alexander Aring < aar @ pengutronix . de >
*
* Based on : net / mac80211 / util . c
*/
# include "ieee802154_i.h"
2015-06-24 12:36:34 +03:00
# include "driver-ops.h"
2014-10-26 11:37:05 +03:00
2014-11-12 05:36:51 +03:00
/* privid for wpan_phys to determine whether they belong to us or not */
const void * const mac802154_wpan_phy_privid = & mac802154_wpan_phy_privid ;
2014-10-26 11:37:05 +03:00
void ieee802154_wake_queue ( struct ieee802154_hw * hw )
{
struct ieee802154_local * local = hw_to_local ( hw ) ;
struct ieee802154_sub_if_data * sdata ;
rcu_read_lock ( ) ;
list_for_each_entry_rcu ( sdata , & local - > interfaces , list ) {
if ( ! sdata - > dev )
continue ;
netif_wake_queue ( sdata - > dev ) ;
}
rcu_read_unlock ( ) ;
}
EXPORT_SYMBOL ( ieee802154_wake_queue ) ;
void ieee802154_stop_queue ( struct ieee802154_hw * hw )
{
struct ieee802154_local * local = hw_to_local ( hw ) ;
struct ieee802154_sub_if_data * sdata ;
rcu_read_lock ( ) ;
list_for_each_entry_rcu ( sdata , & local - > interfaces , list ) {
if ( ! sdata - > dev )
continue ;
netif_stop_queue ( sdata - > dev ) ;
}
rcu_read_unlock ( ) ;
}
EXPORT_SYMBOL ( ieee802154_stop_queue ) ;
2014-11-12 21:51:56 +03:00
enum hrtimer_restart ieee802154_xmit_ifs_timer ( struct hrtimer * timer )
2014-10-26 11:37:05 +03:00
{
2014-11-12 21:51:56 +03:00
struct ieee802154_local * local =
container_of ( timer , struct ieee802154_local , ifs_timer ) ;
ieee802154_wake_queue ( & local - > hw ) ;
return HRTIMER_NORESTART ;
}
void ieee802154_xmit_complete ( struct ieee802154_hw * hw , struct sk_buff * skb ,
bool ifs_handling )
{
if ( ifs_handling ) {
struct ieee802154_local * local = hw_to_local ( hw ) ;
2015-03-04 23:19:59 +03:00
u8 max_sifs_size ;
2014-11-12 21:51:56 +03:00
2015-03-04 23:19:59 +03:00
/* If transceiver sets CRC on his own we need to use lifs
* threshold len above 16 otherwise 18 , because it ' s not
* part of skb - > len .
*/
if ( hw - > flags & IEEE802154_HW_TX_OMIT_CKSUM )
max_sifs_size = IEEE802154_MAX_SIFS_FRAME_SIZE -
IEEE802154_FCS_LEN ;
else
max_sifs_size = IEEE802154_MAX_SIFS_FRAME_SIZE ;
if ( skb - > len > max_sifs_size )
2014-11-12 21:51:56 +03:00
hrtimer_start ( & local - > ifs_timer ,
2016-12-25 14:30:41 +03:00
hw - > phy - > lifs_period * NSEC_PER_USEC ,
2014-11-12 21:51:56 +03:00
HRTIMER_MODE_REL ) ;
else
hrtimer_start ( & local - > ifs_timer ,
2016-12-25 14:30:41 +03:00
hw - > phy - > sifs_period * NSEC_PER_USEC ,
2014-11-12 21:51:56 +03:00
HRTIMER_MODE_REL ) ;
} else {
ieee802154_wake_queue ( hw ) ;
}
2015-05-17 22:44:56 +03:00
dev_consume_skb_any ( skb ) ;
2014-10-26 11:37:05 +03:00
}
EXPORT_SYMBOL ( ieee802154_xmit_complete ) ;
2015-06-24 12:36:34 +03:00
void ieee802154_stop_device ( struct ieee802154_local * local )
{
flush_workqueue ( local - > workqueue ) ;
hrtimer_cancel ( & local - > ifs_timer ) ;
drv_stop ( local ) ;
}