net: Add preliminaly support for suspending/resuming a net interface
Such state needs to be set _from_ the PM API functions and not the other way round. So if a network device driver does not support such API, it will not be able to set the core net_if on PM state, obviously. Currently, these functions only set/unset NET_IF_SUSPENDED flag. More logic will be added later, to decide whether the net_if can be actually set to suspend mode or not and also to take care of all timers related to the interface. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
dee07c9e0a
commit
80917ec16f
3 changed files with 62 additions and 1 deletions
|
@ -194,6 +194,9 @@ enum net_if_flag {
|
||||||
*/
|
*/
|
||||||
NET_IF_NO_AUTO_START,
|
NET_IF_NO_AUTO_START,
|
||||||
|
|
||||||
|
/** Power management specific: interface is being suspended */
|
||||||
|
NET_IF_SUSPENDED,
|
||||||
|
|
||||||
/** @cond INTERNAL_HIDDEN */
|
/** @cond INTERNAL_HIDDEN */
|
||||||
/* Total number of flags - must be at the end of the enum */
|
/* Total number of flags - must be at the end of the enum */
|
||||||
NET_IF_NUM_FLAGS
|
NET_IF_NUM_FLAGS
|
||||||
|
@ -2129,6 +2132,28 @@ static inline bool net_if_are_pending_tx_packets(struct net_if *iface)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_POWER_MANAGEMENT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend a network interface from a power management perspective
|
||||||
|
*
|
||||||
|
* @param iface Pointer to network interface
|
||||||
|
*
|
||||||
|
* @return 0 on success, or -EALREADY/-EBUSY as possible errors.
|
||||||
|
*/
|
||||||
|
int net_if_suspend(struct net_if *iface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume a network interface from a power management perspective
|
||||||
|
*
|
||||||
|
* @param iface Pointer to network interface
|
||||||
|
*
|
||||||
|
* @return 0 on success, or -EALREADY as a possible error.
|
||||||
|
*/
|
||||||
|
int net_if_resume(struct net_if *iface);
|
||||||
|
|
||||||
|
#endif /* CONFIG_NET_POWER_MANAGEMENT */
|
||||||
|
|
||||||
/** @cond INTERNAL_HIDDEN */
|
/** @cond INTERNAL_HIDDEN */
|
||||||
struct net_if_api {
|
struct net_if_api {
|
||||||
void (*init)(struct net_if *iface);
|
void (*init)(struct net_if *iface);
|
||||||
|
|
|
@ -73,6 +73,13 @@ config NETWORKING
|
||||||
|
|
||||||
if NETWORKING
|
if NETWORKING
|
||||||
|
|
||||||
|
# Such option should not be configured manually but by device drivers
|
||||||
|
# which supports PM properly.
|
||||||
|
config NET_POWER_MANAGEMENT
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
depends on DEVICE_POWER_MANAGEMENT
|
||||||
|
|
||||||
source "subsys/net/Kconfig.hostname"
|
source "subsys/net/Kconfig.hostname"
|
||||||
|
|
||||||
source "subsys/net/l2/Kconfig"
|
source "subsys/net/l2/Kconfig"
|
||||||
|
|
|
@ -347,7 +347,8 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt)
|
||||||
enum net_verdict verdict = NET_OK;
|
enum net_verdict verdict = NET_OK;
|
||||||
int status = -EIO;
|
int status = -EIO;
|
||||||
|
|
||||||
if (!net_if_flag_is_set(iface, NET_IF_UP)) {
|
if (!net_if_flag_is_set(iface, NET_IF_UP) ||
|
||||||
|
net_if_flag_is_set(iface, NET_IF_SUSPENDED)) {
|
||||||
/* Drop packet if interface is not up */
|
/* Drop packet if interface is not up */
|
||||||
NET_WARN("iface %p is down", iface);
|
NET_WARN("iface %p is down", iface);
|
||||||
verdict = NET_DROP;
|
verdict = NET_DROP;
|
||||||
|
@ -3623,6 +3624,34 @@ bool net_if_is_promisc(struct net_if *iface)
|
||||||
return net_if_flag_is_set(iface, NET_IF_PROMISC);
|
return net_if_flag_is_set(iface, NET_IF_PROMISC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_POWER_MANAGEMENT
|
||||||
|
|
||||||
|
int net_if_suspend(struct net_if *iface)
|
||||||
|
{
|
||||||
|
if (net_if_are_pending_tx_packets(iface)) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net_if_flag_test_and_set(iface, NET_IF_SUSPENDED)) {
|
||||||
|
return -EALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int net_if_resume(struct net_if *iface)
|
||||||
|
{
|
||||||
|
if (!net_if_flag_is_set(iface, NET_IF_SUSPENDED)) {
|
||||||
|
return -EALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_if_flag_clear(iface, NET_IF_SUSPENDED);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NET_POWER_MANAGEMENT */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_PKT_TIMESTAMP_THREAD)
|
#if defined(CONFIG_NET_PKT_TIMESTAMP_THREAD)
|
||||||
static void net_tx_ts_thread(void)
|
static void net_tx_ts_thread(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue