@@ -18,6 +18,25 @@ LOG_MODULE_REGISTER(net_tc, CONFIG_NET_TC_LOG_LEVEL);
18
18
#include "net_stats.h"
19
19
#include "net_tc_mapping.h"
20
20
21
+ #if NET_TC_RX_COUNT > 1
22
+ #define NET_TC_RX_SLOTS (CONFIG_NET_PKT_RX_COUNT / NET_TC_RX_COUNT)
23
+ BUILD_ASSERT (NET_TC_RX_SLOTS > 0 ,
24
+ "Misconfiguration: There are more traffic classes then packets, "
25
+ "either increase CONFIG_NET_PKT_RX_COUNT or decrease "
26
+ "CONFIG_NET_TC_RX_COUNT" );
27
+ #endif
28
+
29
+ #define TC_TX_PSEUDO_QUEUE (COND_CODE_1(CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO, (1), (0)))
30
+ #define NET_TC_TX_EFFECTIVE_COUNT (NET_TC_TX_COUNT + TC_TX_PSEUDO_QUEUE)
31
+
32
+ #if NET_TC_TX_EFFECTIVE_COUNT > 1
33
+ #define NET_TC_TX_SLOTS (CONFIG_NET_PKT_TX_COUNT / NET_TC_TX_EFFECTIVE_COUNT)
34
+ BUILD_ASSERT (NET_TC_TX_SLOTS > 0 ,
35
+ "Misconfiguration: There are more traffic classes then packets, "
36
+ "either increase CONFIG_NET_PKT_TX_COUNT or decrease "
37
+ "CONFIG_NET_TC_TX_COUNT or disable CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO" );
38
+ #endif
39
+
21
40
/* Template for thread name. The "xx" is either "TX" denoting transmit thread,
22
41
* or "RX" denoting receive thread. The "q[y]" denotes the traffic class queue
23
42
* where y indicates the traffic class id. The value of y can be from 0 to 7.
@@ -40,35 +59,43 @@ static struct net_traffic_class tx_classes[NET_TC_TX_COUNT];
40
59
static struct net_traffic_class rx_classes [NET_TC_RX_COUNT ];
41
60
#endif
42
61
43
- #if NET_TC_RX_COUNT > 0 || NET_TC_TX_COUNT > 0
44
- static void submit_to_queue (struct k_fifo * queue , struct net_pkt * pkt )
45
- {
46
- k_fifo_put (queue , pkt );
47
- }
48
- #endif
49
-
50
- bool net_tc_submit_to_tx_queue (uint8_t tc , struct net_pkt * pkt )
62
+ enum net_verdict net_tc_submit_to_tx_queue (uint8_t tc , struct net_pkt * pkt )
51
63
{
52
64
#if NET_TC_TX_COUNT > 0
53
65
net_pkt_set_tx_stats_tick (pkt , k_cycle_get_32 ());
54
66
55
- submit_to_queue (& tx_classes [tc ].fifo , pkt );
67
+ #if NET_TC_TX_EFFECTIVE_COUNT > 1
68
+ if (k_sem_take (& tx_classes [tc ].fifo_slot , K_NO_WAIT ) != 0 ) {
69
+ return NET_DROP ;
70
+ }
71
+ #endif
72
+
73
+ k_fifo_put (& tx_classes [tc ].fifo , pkt );
74
+ return NET_OK ;
56
75
#else
57
76
ARG_UNUSED (tc );
58
77
ARG_UNUSED (pkt );
78
+ return NET_DROP ;
59
79
#endif
60
- return true;
61
80
}
62
81
63
- void net_tc_submit_to_rx_queue (uint8_t tc , struct net_pkt * pkt )
82
+ enum net_verdict net_tc_submit_to_rx_queue (uint8_t tc , struct net_pkt * pkt )
64
83
{
65
84
#if NET_TC_RX_COUNT > 0
66
85
net_pkt_set_rx_stats_tick (pkt , k_cycle_get_32 ());
67
86
68
- submit_to_queue (& rx_classes [tc ].fifo , pkt );
87
+ #if NET_TC_RX_COUNT > 1
88
+ if (k_sem_take (& rx_classes [tc ].fifo_slot , K_NO_WAIT ) != 0 ) {
89
+ return NET_DROP ;
90
+ }
91
+ #endif
92
+
93
+ k_fifo_put (& rx_classes [tc ].fifo , pkt );
94
+ return NET_OK ;
69
95
#else
70
96
ARG_UNUSED (tc );
71
97
ARG_UNUSED (pkt );
98
+ return NET_DROP ;
72
99
#endif
73
100
}
74
101
@@ -242,10 +269,14 @@ static void net_tc_rx_stats_priority_setup(struct net_if *iface,
242
269
#if NET_TC_RX_COUNT > 0
243
270
static void tc_rx_handler (void * p1 , void * p2 , void * p3 )
244
271
{
245
- ARG_UNUSED (p2 );
246
272
ARG_UNUSED (p3 );
247
273
248
274
struct k_fifo * fifo = p1 ;
275
+ #if NET_TC_RX_COUNT > 1
276
+ struct k_sem * fifo_slot = p2 ;
277
+ #else
278
+ ARG_UNUSED (p2 );
279
+ #endif
249
280
struct net_pkt * pkt ;
250
281
251
282
while (1 ) {
@@ -254,6 +285,10 @@ static void tc_rx_handler(void *p1, void *p2, void *p3)
254
285
continue ;
255
286
}
256
287
288
+ #if NET_TC_RX_COUNT > 1
289
+ k_sem_give (fifo_slot );
290
+ #endif
291
+
257
292
net_process_rx_packet (pkt );
258
293
}
259
294
}
@@ -262,10 +297,14 @@ static void tc_rx_handler(void *p1, void *p2, void *p3)
262
297
#if NET_TC_TX_COUNT > 0
263
298
static void tc_tx_handler (void * p1 , void * p2 , void * p3 )
264
299
{
265
- ARG_UNUSED (p2 );
266
300
ARG_UNUSED (p3 );
267
301
268
302
struct k_fifo * fifo = p1 ;
303
+ #if NET_TC_TX_EFFECTIVE_COUNT > 1
304
+ struct k_sem * fifo_slot = p2 ;
305
+ #else
306
+ ARG_UNUSED (p2 );
307
+ #endif
269
308
struct net_pkt * pkt ;
270
309
271
310
while (1 ) {
@@ -274,6 +313,10 @@ static void tc_tx_handler(void *p1, void *p2, void *p3)
274
313
continue ;
275
314
}
276
315
316
+ #if NET_TC_TX_EFFECTIVE_COUNT > 1
317
+ k_sem_give (fifo_slot );
318
+ #endif
319
+
277
320
net_process_tx_packet (pkt );
278
321
}
279
322
}
@@ -318,10 +361,20 @@ void net_tc_tx_init(void)
318
361
319
362
k_fifo_init (& tx_classes [i ].fifo );
320
363
364
+ #if NET_TC_TX_EFFECTIVE_COUNT > 1
365
+ k_sem_init (& tx_classes [i ].fifo_slot , NET_TC_TX_SLOTS , NET_TC_TX_SLOTS );
366
+ #endif
367
+
321
368
tid = k_thread_create (& tx_classes [i ].handler , tx_stack [i ],
322
369
K_KERNEL_STACK_SIZEOF (tx_stack [i ]),
323
370
tc_tx_handler ,
324
- & tx_classes [i ].fifo , NULL , NULL ,
371
+ & tx_classes [i ].fifo ,
372
+ #if NET_TC_TX_EFFECTIVE_COUNT > 1
373
+ & tx_classes [i ].fifo_slot ,
374
+ #else
375
+ NULL ,
376
+ #endif
377
+ NULL ,
325
378
priority , 0 , K_FOREVER );
326
379
if (!tid ) {
327
380
NET_ERR ("Cannot create TC handler thread %d" , i );
@@ -376,10 +429,20 @@ void net_tc_rx_init(void)
376
429
377
430
k_fifo_init (& rx_classes [i ].fifo );
378
431
432
+ #if NET_TC_RX_COUNT > 1
433
+ k_sem_init (& rx_classes [i ].fifo_slot , NET_TC_RX_SLOTS , NET_TC_RX_SLOTS );
434
+ #endif
435
+
379
436
tid = k_thread_create (& rx_classes [i ].handler , rx_stack [i ],
380
437
K_KERNEL_STACK_SIZEOF (rx_stack [i ]),
381
438
tc_rx_handler ,
382
- & rx_classes [i ].fifo , NULL , NULL ,
439
+ & rx_classes [i ].fifo ,
440
+ #if NET_TC_RX_COUNT > 1
441
+ & rx_classes [i ].fifo_slot ,
442
+ #else
443
+ NULL ,
444
+ #endif
445
+ NULL ,
383
446
priority , 0 , K_FOREVER );
384
447
if (!tid ) {
385
448
NET_ERR ("Cannot create TC handler thread %d" , i );
0 commit comments