netdev_upperhalf: convert Kconfig to variable
Build Documentation / build-html (push) Has been cancelled

Upperhalf supports multiple working modes at the same time,
which is specified by NIC when register

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-06-11 16:59:58 +08:00
committed by Xiang Xiao
parent 84895c8e70
commit aa8ffea3cf
41 changed files with 204 additions and 221 deletions
@@ -73,6 +73,16 @@ Here is a guide to do so:
is set to 5, it means that if the driver has 5 unreleased packets
(``netpkt_free``), the upper-half will not call ``transmit`` until they
are released.
9. Find a suitable ``rxtype`` for the driver, and set it in the driver
initialization function. There are some types of receive notification
methods, defined in ``enum netdev_rx_e``, like ``NETDEV_RX_WORK``,
``NETDEV_RX_THREAD`` and ``NETDEV_RX_THREAD_RSS``. Choose the one that
fits your driver best.
10. Find a suitable ``priority`` for the driver, and set it in the driver
initialization function. This is the priority for the receive
notification work queue or thread. when ``rxtype`` is ``NETDEV_RX_WORK``,
it is the work queue ``qid``; when ``rxtype`` is ``NETDEV_RX_THREAD``,
it is the thread priority.
- Note: An exception is that if the net stack is replying for RX packet,
this replied packet will always be put into ``transmit``, which may
@@ -130,6 +140,8 @@ Here is a guide to do so:
dev->quota[NETPKT_TX] = 1;
dev->quota[NETPKT_RX] = 1;
dev->rxtype = NETDEV_RX_WORK;
dev->priority = HPWORK;
return netdev_lower_register(dev, NET_LL_ETHERNET);
}
@@ -1218,6 +1218,8 @@ static int esp_wlan_initialize(uint32_t mode)
priv->dev.quota[NETPKT_RX] = RX_BUF_COUNT;
priv->dev.quota[NETPKT_TX] = TX_BUF_COUNT;
priv->dev.rxtype = NETDEV_RX_THREAD;
priv->dev.priority = 100;
IOB_QINIT(&priv->netdev_rx_queue);
@@ -475,6 +475,8 @@ int esp_openeth_initialize(void)
dev->quota[NETPKT_TX] = TX_BUF_COUNT;
dev->quota[NETPKT_RX] = RX_BUF_COUNT;
dev->rxtype = NETDEV_RX_THREAD;
dev->priority = 100;
/* Allocate DMA buffers */
@@ -1221,6 +1221,8 @@ static int esp_wlan_initialize(uint32_t mode)
priv->dev.quota[NETPKT_RX] = RX_BUF_COUNT;
priv->dev.quota[NETPKT_TX] = TX_BUF_COUNT;
priv->dev.rxtype = NETDEV_RX_THREAD;
priv->dev.priority = 100;
IOB_QINIT(&priv->netdev_rx_queue);
@@ -55,7 +55,6 @@ CONFIG_NET=y
CONFIG_NETDEV_CAN_BITRATE_IOCTL=y
CONFIG_NETDEV_IFINDEX=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NET_CAN=y
CONFIG_NET_CAN_EXTID=y
CONFIG_NET_CAN_NOTIFIER=y
@@ -42,7 +42,6 @@ CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_MAC802154_NTXDESC=36
CONFIG_MM_REGIONS=2
CONFIG_NET=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_STATISTICS=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
@@ -42,7 +42,6 @@ CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_MAC802154_NTXDESC=36
CONFIG_MM_REGIONS=2
CONFIG_NET=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_STATISTICS=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
@@ -42,7 +42,6 @@ CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_MAC802154_NTXDESC=36
CONFIG_MM_REGIONS=2
CONFIG_NET=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_STATISTICS=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
@@ -42,7 +42,6 @@ CONFIG_MM_REGIONS=2
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x08080808
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_WEBCLIENT=y
CONFIG_NET_LL_GUARDSIZE=14
CONFIG_NET_USRSOCK=y
@@ -95,7 +95,6 @@ CONFIG_LV_USE_QRCODE=y
CONFIG_MTD=y
CONFIG_MTD_CFI=y
CONFIG_NET=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_IFINDEX=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NET_SOCKOPTS=y
@@ -35,7 +35,6 @@ CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x08080808
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETINIT_DHCPC=y
CONFIG_NETINIT_NOMAC=y
CONFIG_NET_ETH_PKTSIZE=1516
@@ -42,7 +42,6 @@ CONFIG_MMCSD_MULTIBLOCK_LIMIT=1
CONFIG_MMCSD_SDIO=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETUTILS_PLCATOOL=y
@@ -36,7 +36,6 @@ CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x08080808
CONFIG_NETDEV_PHY_DEBUG=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETINIT_DHCPC=y
CONFIG_NETINIT_DRIPADDR=0x08080808
CONFIG_NETINIT_NOMAC=y
@@ -106,8 +106,6 @@ CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_IFINDEX=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETDEV_WORK_THREAD_PRIORITY=180
CONFIG_NET_ARP_IPIN=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ETH_PKTSIZE=1478
@@ -111,8 +111,6 @@ CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_IFINDEX=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETDEV_WORK_THREAD_PRIORITY=180
CONFIG_NET_ARP_IPIN=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ETH_PKTSIZE=1478
@@ -44,7 +44,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_WEBCLIENT=y
CONFIG_NET_BROADCAST=y
@@ -43,7 +43,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NETUTILS_IPERF=y
@@ -40,7 +40,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NET_BROADCAST=y
@@ -40,7 +40,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ICMP_SOCKET=y
@@ -45,7 +45,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_WEBCLIENT=y
CONFIG_NET_BROADCAST=y
@@ -44,7 +44,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NETUTILS_IPERF=y
@@ -39,7 +39,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NET_BROADCAST=y
@@ -44,7 +44,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NET_BROADCAST=y
@@ -44,7 +44,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NET_BROADCAST=y
@@ -41,7 +41,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ICMP_SOCKET=y
@@ -91,7 +91,6 @@ CONFIG_LINE_MAX=200
CONFIG_MM_IOB=y
CONFIG_MQ_MAXMSGSIZE=128
CONFIG_NET=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_IFINDEX=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NET_LOCAL=y
@@ -60,7 +60,6 @@ CONFIG_MATTER=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x771d1d1d
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETINIT_IPADDR=0x0a000102
CONFIG_NETLINK_ROUTE=y
CONFIG_NETUTILS_JSONCPP=y
@@ -63,7 +63,6 @@ CONFIG_LIBM=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETINIT_DRIPADDR=0xc0a80801
CONFIG_NETINIT_IPADDR=0x0a000102
CONFIG_NETUTILS_CODECS=y
@@ -35,7 +35,6 @@ CONFIG_MM_REGIONS=3
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x0a000203
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETINIT_DRIPADDR=0x0a000202
CONFIG_NETINIT_IPADDR=0x0a000215
CONFIG_NET_BINDTODEVICE=y
@@ -50,7 +50,6 @@ CONFIG_NETDB_DNSCLIENT_NAMESIZE=64
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NETUTILS_IPERF=y
@@ -48,7 +48,6 @@ CONFIG_NETDB_DNSCLIENT_NAMESIZE=64
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NET_BROADCAST=y
@@ -44,7 +44,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NETUTILS_IPERF=y
@@ -42,7 +42,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NET_ETH_PKTSIZE=1514
@@ -64,7 +64,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NET_BROADCAST=y
@@ -69,7 +69,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_WEBCLIENT=y
CONFIG_NET_BROADCAST=y
@@ -35,7 +35,6 @@ CONFIG_LINE_MAX=64
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x0a000203
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETINIT_DRIPADDR=0x0a000202
CONFIG_NETINIT_IPADDR=0x0a000215
CONFIG_NET_BINDTODEVICE=y
@@ -45,7 +45,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_DHCPD=y
CONFIG_NETUTILS_IPERF=y
@@ -43,7 +43,6 @@ CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDEV_WIRELESS_IOCTL=y
CONFIG_NETDEV_WORK_THREAD=y
CONFIG_NETUTILS_CJSON=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NET_ETH_PKTSIZE=1514
-39
View File
@@ -22,37 +22,6 @@ if NETDEVICES
comment "Upper-half Network Device Driver Options"
choice
prompt "Netdev poll worker"
config NETDEV_LPWORK_THREAD
bool "Use low-priority worker thread to do netdev poll"
depends on SCHED_LPWORK
config NETDEV_HPWORK_THREAD
bool "Use high-priority worker thread to do netdev poll"
depends on SCHED_HPWORK
config NETDEV_WORK_THREAD
bool "Use a dedicated work thread to do netdev poll"
endchoice # Netdev poll worker
config NETDEV_WORK_THREAD_POLLING_PERIOD
int "Polling period, the units are microseconds"
default 0
depends on NETDEV_WORK_THREAD
---help---
Disable the txdone and rxready interrupt and use polling
period to receive packets when the value is not 0.
config NETDEV_WORK_THREAD_PRIORITY
int "Priority of work poll thread"
default 100
depends on NETDEV_WORK_THREAD
---help---
The priority of work poll thread in netdev.
config NETDEV_WIRELESS_HANDLER
bool "Support wireless handler in upper-half driver"
default y
@@ -60,14 +29,6 @@ config NETDEV_WIRELESS_HANDLER
---help---
Enable the wireless handler support in upper-half driver.
config NETDEV_RSS
bool "Using hardware RSS (Receive Side Scaling) with network card"
default n
depends on SMP && NETDEV_IOCTL && NETDEV_WORK_THREAD
---help---
When the hardware supports RSS/aRFS function, provide the
hash value and CPU ID to the hardware driver.
menuconfig MDIO_BUS
bool "Upper-half MDIO Bus Driver Options"
default y
+176 -142
View File
@@ -51,18 +51,6 @@
#define NETDEV_THREAD_NAME_FMT "netdev-%s"
#ifdef CONFIG_NETDEV_HPWORK_THREAD
# define NETDEV_WORK HPWORK
#else
# define NETDEV_WORK LPWORK
#endif
#ifdef CONFIG_NETDEV_RSS
# define NETDEV_THREAD_COUNT CONFIG_SMP_NCPUS
#else
# define NETDEV_THREAD_COUNT 1
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@@ -75,22 +63,19 @@ struct netdev_vlan_entry_s
};
#endif
struct netdev_thread_s
{
pid_t tid;
sem_t sem;
sem_t sem_exit;
};
/* This structure describes the state of the upper half driver */
struct netdev_upperhalf_s
{
FAR struct netdev_lowerhalf_s *lower;
/* Deferring poll work to work queue or thread */
#ifdef CONFIG_NETDEV_WORK_THREAD
pid_t tid[NETDEV_THREAD_COUNT];
sem_t sem[NETDEV_THREAD_COUNT];
sem_t sem_exit[NETDEV_THREAD_COUNT];
#else
struct work_s work;
#endif
/* TX queue for re-queueing replies */
#if CONFIG_IOB_NCHAINS > 0
@@ -100,6 +85,14 @@ struct netdev_upperhalf_s
#ifdef CONFIG_NET_VLAN
struct netdev_vlan_entry_s vlan[CONFIG_NET_VLAN_COUNT];
#endif
/* Deferring process to work queue or thread */
union
{
struct netdev_thread_s thread[0];
struct work_s work[0];
};
};
/****************************************************************************
@@ -214,7 +207,7 @@ static void netpkt_put(FAR struct net_driver_s *dev, FAR netpkt_t *pkt,
****************************************************************************/
static FAR struct netdev_upperhalf_s *
netdev_upper_alloc(FAR struct netdev_lowerhalf_s *dev)
netdev_upper_alloc(FAR struct netdev_lowerhalf_s *dev, size_t extra_size)
{
/* Allocate the upper-half data structure */
@@ -222,7 +215,7 @@ netdev_upper_alloc(FAR struct netdev_lowerhalf_s *dev)
DEBUGASSERT(dev != NULL && dev->netdev.d_private == NULL);
upper = kmm_zalloc(sizeof(struct netdev_upperhalf_s));
upper = kmm_zalloc(sizeof(struct netdev_upperhalf_s) + extra_size);
if (upper == NULL)
{
nerr("ERROR: Allocation failed\n");
@@ -786,27 +779,6 @@ static void netdev_upper_work(FAR void *arg)
net_unlock();
}
/****************************************************************************
* Name: netdev_upper_wait
*
* Description:
* Wait for timeout or signal.
*
****************************************************************************/
#ifdef CONFIG_NETDEV_WORK_THREAD
static int netdev_upper_wait(FAR sem_t *sem)
{
#if CONFIG_NETDEV_WORK_THREAD_POLLING_PERIOD > 0
int ret =
nxsem_tickwait(sem, USEC2TICK(CONFIG_NETDEV_WORK_THREAD_POLLING_PERIOD));
return ret == -ETIMEDOUT ? OK : ret;
#else
return nxsem_wait(sem);
#endif
}
/****************************************************************************
* Name: netdev_upper_loop
*
@@ -820,26 +792,26 @@ static int netdev_upper_loop(int argc, FAR char *argv[])
FAR struct netdev_upperhalf_s *upper =
(FAR struct netdev_upperhalf_s *)((uintptr_t)strtoul(argv[1], NULL, 16));
int cpu = atoi(argv[2]);
FAR struct netdev_thread_s *t = &upper->thread[cpu];
#ifdef CONFIG_NETDEV_RSS
cpu_set_t cpuset;
if (upper->lower->rxtype == NETDEV_RX_THREAD_RSS)
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
sched_setaffinity(upper->tid[cpu], sizeof(cpu_set_t), &cpuset);
#endif
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
sched_setaffinity(t->tid, sizeof(cpu_set_t), &cpuset);
}
while (netdev_upper_wait(&upper->sem[cpu]) == OK &&
upper->tid[cpu] != INVALID_PROCESS_ID)
while (nxsem_wait(&t->sem) == OK && t->tid != INVALID_PROCESS_ID)
{
netdev_upper_work(upper);
}
nwarn("WARNING: Netdev work thread quitting.");
nxsem_post(&upper->sem_exit[cpu]);
nxsem_post(&t->sem_exit);
return 0;
}
#endif
/****************************************************************************
* Name: netdev_upper_queue_work
@@ -855,28 +827,36 @@ static int netdev_upper_loop(int argc, FAR char *argv[])
static inline void netdev_upper_queue_work(FAR struct net_driver_s *dev)
{
FAR struct netdev_upperhalf_s *upper = dev->d_private;
int cpu = 0;
#ifdef CONFIG_NETDEV_WORK_THREAD
# ifdef CONFIG_NETDEV_RSS
int cpu = this_cpu();
# else
const int cpu = 0;
# endif
int semcount;
if (nxsem_get_value(&upper->sem[cpu], &semcount) == OK &&
semcount <= 0)
switch (upper->lower->rxtype)
{
nxsem_post(&upper->sem[cpu]);
}
#else
if (work_available(&upper->work))
{
/* Schedule to serialize the poll on the worker thread. */
case NETDEV_RX_WORK:
{
FAR struct work_s *work = upper->work;
if (work_available(work))
{
/* Schedule to serialize the poll on the worker thread. */
work_queue(NETDEV_WORK, &upper->work, netdev_upper_work, upper, 0);
work_queue(upper->lower->priority, work, netdev_upper_work,
upper, 0);
}
}
break;
case NETDEV_RX_THREAD_RSS:
cpu = this_cpu();
case NETDEV_RX_THREAD:
{
FAR struct netdev_thread_s *t = &upper->thread[cpu];
int semcount;
if (nxsem_get_value(&t->sem, &semcount) == OK && semcount <= 0)
{
nxsem_post(&t->sem);
}
}
break;
}
#endif
}
/****************************************************************************
@@ -1173,6 +1153,40 @@ int netdev_upper_vlan_ioctl(FAR struct netdev_lowerhalf_s *lower,
}
#endif /* CONFIG_NET_VLAN */
/****************************************************************************
* Name: netdev_upper_exit_thread
*
* Description:
* Exit the dedicated thread
*
****************************************************************************/
static void netdev_upper_exit_thread(FAR struct netdev_upperhalf_s *upper)
{
int cpu = 1;
switch (upper->lower->rxtype)
{
case NETDEV_RX_THREAD_RSS:
cpu = CONFIG_SMP_NCPUS;
case NETDEV_RX_THREAD:
while (--cpu >= 0)
{
FAR struct netdev_thread_s *t = &upper->thread[cpu];
if (t->tid >= 0)
{
/* Try to tear down the dedicated thread for work. */
t->tid = INVALID_PROCESS_ID;
nxsem_post(&t->sem);
nxsem_wait(&t->sem_exit);
}
}
break;
}
}
/****************************************************************************
* Name: netdev_upper_ifup/ifdown/addmac/rmmac/ioctl
*
@@ -1184,42 +1198,45 @@ int netdev_upper_vlan_ioctl(FAR struct netdev_lowerhalf_s *lower,
static int netdev_upper_ifup(FAR struct net_driver_s *dev)
{
FAR struct netdev_upperhalf_s *upper = dev->d_private;
int cpu = 1;
#ifdef CONFIG_NETDEV_WORK_THREAD
int i;
/* Try to bring up a dedicated thread for work. */
for (i = 0; i < NETDEV_THREAD_COUNT; i++)
switch (upper->lower->rxtype)
{
if (upper->tid[i] <= 0)
{
FAR char *argv[3];
char arg1[32];
char arg2[32];
char name[32];
case NETDEV_RX_THREAD_RSS:
cpu = CONFIG_SMP_NCPUS;
case NETDEV_RX_THREAD:
snprintf(arg1, sizeof(arg1), "%p", upper);
argv[0] = arg1;
/* Try to bring up a dedicated thread for work. */
snprintf(arg2, sizeof(arg2), "%d", i);
argv[1] = arg2;
argv[2] = NULL;
while (--cpu >= 0)
{
FAR struct netdev_thread_s *t = &upper->thread[cpu];
FAR char *argv[3];
char arg1[32];
char arg2[32];
char name[32];
snprintf(name, sizeof(name), NETDEV_THREAD_NAME_FMT,
dev->d_ifname);
snprintf(arg1, sizeof(arg1), "%p", upper);
argv[0] = arg1;
upper->tid[i] = kthread_create(name,
CONFIG_NETDEV_WORK_THREAD_PRIORITY,
CONFIG_DEFAULT_TASK_STACKSIZE,
netdev_upper_loop, argv);
if (upper->tid[i] < 0)
{
return upper->tid[i];
}
}
snprintf(arg2, sizeof(arg2), "%d", cpu);
argv[1] = arg2;
argv[2] = NULL;
snprintf(name, sizeof(name), NETDEV_THREAD_NAME_FMT,
dev->d_ifname);
t->tid = kthread_create(name, upper->lower->priority,
CONFIG_DEFAULT_TASK_STACKSIZE,
netdev_upper_loop, argv);
if (t->tid < 0)
{
netdev_upper_exit_thread(upper);
return t->tid;
}
}
break;
}
#endif
if (upper->lower->ops->ifup)
{
@@ -1233,9 +1250,16 @@ static int netdev_upper_ifdown(FAR struct net_driver_s *dev)
{
FAR struct netdev_upperhalf_s *upper = dev->d_private;
#ifndef CONFIG_NETDEV_WORK_THREAD
work_cancel(NETDEV_WORK, &upper->work);
#endif
switch (upper->lower->rxtype)
{
case NETDEV_RX_WORK:
work_cancel_sync(upper->lower->priority, upper->work);
break;
case NETDEV_RX_THREAD:
case NETDEV_RX_THREAD_RSS:
netdev_upper_exit_thread(upper);
break;
}
if (upper->lower->ops->ifdown)
{
@@ -1336,10 +1360,9 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
enum net_lltype_e lltype)
{
FAR struct netdev_upperhalf_s *upper;
size_t extra_size;
int cpu = 0;
int ret;
#ifdef CONFIG_NETDEV_WORK_THREAD
int i;
#endif
if (dev == NULL || dev->ops == NULL ||
dev->ops->transmit == NULL || dev->ops->receive == NULL)
@@ -1358,7 +1381,25 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
return -EINVAL;
}
if ((upper = netdev_upper_alloc(dev)) == NULL)
switch (dev->rxtype)
{
case NETDEV_RX_WORK:
extra_size = sizeof(struct work_s);
break;
case NETDEV_RX_THREAD:
extra_size = sizeof(struct netdev_thread_s);
cpu = 1;
break;
case NETDEV_RX_THREAD_RSS:
extra_size = sizeof(struct netdev_thread_s) * CONFIG_SMP_NCPUS;
cpu = CONFIG_SMP_NCPUS;
break;
default:
nerr("ERROR: Unrecognized device rxtype: %d\n", dev->rxtype);
return -EINVAL;
}
if ((upper = netdev_upper_alloc(dev, extra_size)) == NULL)
{
return -ENOMEM;
}
@@ -1382,17 +1423,15 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
kmm_free(upper);
dev->netdev.d_private = NULL;
}
#ifdef CONFIG_NETDEV_WORK_THREAD
else
while (--cpu >= 0)
{
for (i = 0; i < NETDEV_THREAD_COUNT; i++)
{
upper->tid[i] = INVALID_PROCESS_ID;
nxsem_init(&upper->sem[i], 0, 0);
nxsem_init(&upper->sem_exit[i], 0, 0);
}
FAR struct netdev_thread_s *t = &upper->thread[cpu];
t->tid = INVALID_PROCESS_ID;
nxsem_init(&t->sem, 0, 0);
nxsem_init(&t->sem_exit, 0, 0);
}
#endif
return ret;
}
@@ -1414,10 +1453,8 @@ int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev,
int netdev_lower_unregister(FAR struct netdev_lowerhalf_s *dev)
{
FAR struct netdev_upperhalf_s *upper;
int cpu = 1;
int ret;
#ifdef CONFIG_NETDEV_WORK_THREAD
int i;
#endif
if (dev == NULL || dev->netdev.d_private == NULL)
{
@@ -1437,22 +1474,24 @@ int netdev_lower_unregister(FAR struct netdev_lowerhalf_s *dev)
return ret;
}
#ifdef CONFIG_NETDEV_WORK_THREAD
for (i = 0; i < NETDEV_THREAD_COUNT; i++)
switch (dev->rxtype)
{
if (upper->tid[i] > 0)
{
/* Try to tear down the dedicated thread for work. */
case NETDEV_RX_THREAD_RSS:
cpu = CONFIG_SMP_NCPUS;
case NETDEV_RX_THREAD:
upper->tid[i] = INVALID_PROCESS_ID;
nxsem_post(&upper->sem[i]);
nxsem_wait(&upper->sem_exit[i]);
}
/* Stop the dedicated thread for network operations in thread mode */
nxsem_destroy(&upper->sem[i]);
nxsem_destroy(&upper->sem_exit[i]);
netdev_upper_exit_thread(upper);
while (--cpu >= 0)
{
FAR struct netdev_thread_s *t = &upper->thread[cpu];
nxsem_destroy(&t->sem);
nxsem_destroy(&t->sem_exit);
}
break;
}
#endif
#if CONFIG_IOB_NCHAINS > 0
iob_free_queue(&upper->txq);
@@ -1521,13 +1560,11 @@ void netdev_lower_carrier_off(FAR struct netdev_lowerhalf_s *dev)
void netdev_lower_rxready(FAR struct netdev_lowerhalf_s *dev)
{
#if CONFIG_NETDEV_WORK_THREAD_POLLING_PERIOD == 0
/* Note: Don't need to handle VLAN here, because RX of VLAN is handled in
* eth_input.
/* Note: Don't need to handle VLAN here, because RX of VLAN is handled
* in eth_input.
*/
netdev_upper_queue_work(&dev->netdev);
#endif
}
/****************************************************************************
@@ -1543,14 +1580,11 @@ void netdev_lower_rxready(FAR struct netdev_lowerhalf_s *dev)
void netdev_lower_txdone(FAR struct netdev_lowerhalf_s *dev)
{
#if CONFIG_NETDEV_WORK_THREAD_POLLING_PERIOD == 0
# ifdef CONFIG_NET_VLAN
#ifdef CONFIG_NET_VLAN
FAR struct netdev_upperhalf_s *upper = dev->netdev.d_private;
netdev_upper_vlan_foreach(upper, netdev_lower_txdone);
# endif
netdev_upper_queue_work(&dev->netdev);
#endif
netdev_upper_queue_work(&dev->netdev);
NETDEV_TXDONE(&dev->netdev);
}
+10 -4
View File
@@ -44,10 +44,6 @@
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_NETDEV_WORK_THREAD_POLLING_PERIOD
# define CONFIG_NETDEV_WORK_THREAD_POLLING_PERIOD 0
#endif
/* Layout for net packet:
*
* | <-------------- NETPKT_BUFLEN ---------------> |
@@ -91,6 +87,13 @@ enum netpkt_type_e
NETPKT_TYPENUM
};
enum netdev_rx_e
{
NETDEV_RX_WORK, /* Use work queue thread */
NETDEV_RX_THREAD, /* Upper half dedicated thread */
NETDEV_RX_THREAD_RSS /* RSS mode, upper half thread */
};
/* This structure is the generic form of state structure used by lower half
* netdev driver. This state structure is passed to the netdev driver when
* the driver is initialized. Then, on subsequent callbacks into the lower
@@ -120,6 +123,9 @@ struct netdev_lowerhalf_s
FAR atomic_t *quota_ptr; /* Shared quota, ignore `quota` if ptr is set */
atomic_t quota[NETPKT_TYPENUM];
uint8_t rxtype;
uint8_t priority;
/* The structure used by net stack.
* Note: Do not change its fields unless you know what you are doing.
*