diff --git a/include/net/if.h b/include/net/if.h index 8128a75e71..b5db231748 100644 --- a/include/net/if.h +++ b/include/net/if.h @@ -198,6 +198,16 @@ struct can_ioctl_filter_s uint8_t fprio; /* See CAN_MSGPRIO_* definitions */ }; +/* Define an enumeration type that describes the CAN/LIN state */ + +enum can_ioctl_state_e +{ + CAN_STATE_OPERATIONAL = 1, /* The can/lin controller is in the awake state */ + CAN_STATE_SLEEP, /* The can/lin controller is in the sleep state */ + CAN_STATE_SPENDING, /* The can/lin controller is preparing to enter sleep state */ + CAN_STATE_BUSY /* The can/lin bus is busy */ +}; + /* There are two forms of the I/F request structure. * One for IPv6 and one for IPv4. * Notice that they are (and must be) cast compatible and really different @@ -224,6 +234,7 @@ struct lifreq struct mii_ioctl_data_s lifru_mii_data; /* MII request data */ struct can_ioctl_data_s lifru_can_data; /* CAN bitrate request data */ struct can_ioctl_filter_s lifru_can_filter; /* CAN filter request data */ + enum can_ioctl_state_e lifru_can_state; /* CAN/LIN controller state */ } lifr_ifru; }; @@ -277,6 +288,7 @@ struct ifreq struct mii_ioctl_data_s ifru_mii_data; /* MII request data */ struct can_ioctl_data_s ifru_can_data; /* CAN bitrate request data */ struct can_ioctl_filter_s ifru_can_filter; /* CAN filter request data */ + enum can_ioctl_state_e ifru_can_state; /* CAN/LIN controller state */ FAR void *ifru_data; /* For use by interface */ } ifr_ifru; }; diff --git a/include/nuttx/net/ioctl.h b/include/nuttx/net/ioctl.h index 0d0a7e37d8..555c16f23b 100644 --- a/include/nuttx/net/ioctl.h +++ b/include/nuttx/net/ioctl.h @@ -125,6 +125,8 @@ #define SIOCACANSTDFILTER _SIOC(0x0030) /* Add hardware-level standard ID filter */ #define SIOCDCANSTDFILTER _SIOC(0x0031) /* Delete hardware-level standard ID filter */ #define SIOCCANRECOVERY _SIOC(0x0032) /* Recovery can, work only when bus-off state */ +#define SIOCGCANSTATE _SIOC(0x003E) /* Get state from a CAN/LIN controller */ +#define SIOCSCANSTATE _SIOC(0x003F) /* Set the LIN/CAN controller state */ /* Network socket control ***************************************************/ diff --git a/net/netdev/Kconfig b/net/netdev/Kconfig index 27ba60c5e8..227b5c2d58 100644 --- a/net/netdev/Kconfig +++ b/net/netdev/Kconfig @@ -33,6 +33,15 @@ config NETDEV_CAN_FILTER_IOCTL Enable support for ioctl() commands to add/remove CAN hardware-level filters (NOTE: Not supported by all drivers) +config NETDEV_CAN_STATE_IOCTL + bool "Enable CAN state ioctl()" + default n + select NETDEV_IOCTL + depends on NET_CAN + ---help--- + Enable support for ioctl() commands to set/see CAN or LIN controller-state + (NOTE: Not supported by all drivers) + config NETDEV_WIRELESS_IOCTL bool "Enable Wireless ioctl()" default n diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 461eef8513..f39ab83fc5 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -726,6 +726,8 @@ static ssize_t net_ioctl_ifreq_arglen(uint8_t domain, int cmd) case SIOCACANSTDFILTER: case SIOCDCANSTDFILTER: case SIOCCANRECOVERY: + case SIOCGCANSTATE: + case SIOCSCANSTATE: case SIOCSIFNAME: case SIOCGIFNAME: case SIOCGIFINDEX: @@ -1210,6 +1212,23 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd, break; #endif +#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_CAN_STATE_IOCTL) + case SIOCGCANSTATE: /* Get state from a CAN/LIN controller */ + case SIOCSCANSTATE: /* Set the LIN/CAN controller state */ + if (dev->d_ioctl) + { + FAR enum can_ioctl_state_e *can_state = + &req->ifr_ifru.ifru_can_state; + ret = dev->d_ioctl(dev, cmd, + (unsigned long)(uintptr_t)can_state); + } + else + { + ret = -ENOSYS; + } + break; +#endif + #ifdef CONFIG_NETDEV_IFINDEX case SIOCGIFINDEX: /* Index to name mapping */ req->ifr_ifindex = dev->d_ifindex;