@@ -106,45 +106,55 @@ static void canbus_rx_report_err(struct net_pkt *pkt)
106106 net_pkt_unref (pkt );
107107}
108108
109- static void rx_err_work_handler (struct k_work * item )
109+ static void rx_err_work_handler (struct net_pkt * pkt )
110110{
111- struct net_pkt * pkt = CONTAINER_OF (item , struct net_pkt , work );
112-
113111 canbus_rx_report_err (pkt );
114112}
115113
116- static void canbus_rx_report_err_from_isr ( struct net_pkt * pkt )
114+ static void submit_to_queue ( struct k_fifo * queue , struct net_pkt * pkt )
117115{
118- k_work_init (& pkt -> work , rx_err_work_handler );
119- k_work_submit_to_queue (& net_canbus_workq , & pkt -> work );
116+ k_fifo_put (queue , pkt );
117+ }
118+
119+ static void canbus_rx_report_err_from_isr (struct k_fifo * queue ,
120+ struct net_pkt * pkt )
121+ {
122+ submit_to_queue (queue , pkt );
120123}
121124
122125static void canbus_tx_timeout (struct _timeout * t )
123126{
124127 struct canbus_isotp_tx_ctx * ctx =
125128 CONTAINER_OF (t , struct canbus_isotp_tx_ctx , timeout );
129+ struct net_if * iface = net_pkt_iface (ctx -> pkt );
130+ struct canbus_net_ctx * net_ctx = net_if_l2_data (iface );
126131
127132 NET_ERR ("TX Timeout. CTX: %p" , ctx );
128133 ctx -> state = NET_CAN_TX_STATE_ERR ;
129- k_work_submit_to_queue (& net_canbus_workq , & ctx -> pkt -> work );
134+
135+ submit_to_queue (& net_ctx -> tx_queue , ctx -> pkt );
130136}
131137
132138static void canbus_rx_timeout (struct _timeout * t )
133139{
134140 struct canbus_isotp_rx_ctx * ctx =
135141 CONTAINER_OF (t , struct canbus_isotp_rx_ctx , timeout );
142+ struct net_if * iface = net_pkt_iface (ctx -> pkt );
143+ struct canbus_net_ctx * net_ctx = net_if_l2_data (iface );
136144
137145 NET_ERR ("RX Timeout. CTX: %p" , ctx );
138146 ctx -> state = NET_CAN_RX_STATE_TIMEOUT ;
139- canbus_rx_report_err_from_isr (ctx -> pkt );
147+ canbus_rx_report_err_from_isr (& net_ctx -> rx_err_queue , ctx -> pkt );
140148}
141149
142150static void canbus_st_min_timeout (struct _timeout * t )
143151{
144152 struct canbus_isotp_tx_ctx * ctx =
145153 CONTAINER_OF (t , struct canbus_isotp_tx_ctx , timeout );
154+ struct net_if * iface = net_pkt_iface (ctx -> pkt );
155+ struct canbus_net_ctx * net_ctx = net_if_l2_data (iface );
146156
147- k_work_submit_to_queue ( & net_canbus_workq , & ctx -> pkt -> work );
157+ submit_to_queue ( & net_ctx -> tx_queue , ctx -> pkt );
148158}
149159
150160static k_timeout_t canbus_stmin_to_ticks (uint8_t stmin )
@@ -682,6 +692,8 @@ static void canbus_tx_frame_isr(uint32_t err_flags, void *arg)
682692{
683693 struct net_pkt * pkt = (struct net_pkt * )arg ;
684694 struct canbus_isotp_tx_ctx * ctx = pkt -> canbus_tx_ctx ;
695+ struct net_if * iface = net_pkt_iface (pkt );
696+ struct canbus_net_ctx * net_ctx = net_if_l2_data (iface );
685697
686698 ctx -> tx_backlog -- ;
687699
@@ -693,7 +705,7 @@ static void canbus_tx_frame_isr(uint32_t err_flags, void *arg)
693705 ctx -> state = NET_CAN_TX_STATE_FIN ;
694706 }
695707
696- k_work_submit_to_queue ( & net_canbus_workq , & pkt -> work );
708+ submit_to_queue ( & net_ctx -> tx_queue , pkt );
697709}
698710
699711static inline int canbus_send_cf (struct net_pkt * pkt )
@@ -792,13 +804,6 @@ static void canbus_tx_work(struct net_pkt *pkt)
792804 }
793805}
794806
795- static void canbus_tx_work_handler (struct k_work * item )
796- {
797- struct net_pkt * pkt = CONTAINER_OF (item , struct net_pkt , work );
798-
799- canbus_tx_work (pkt );
800- }
801-
802807static enum net_verdict canbus_process_fc_data (struct canbus_isotp_tx_ctx * ctx ,
803808 struct net_pkt * pkt )
804809{
@@ -855,6 +860,8 @@ static enum net_verdict canbus_process_fc(struct net_pkt *pkt)
855860 struct canbus_isotp_tx_ctx * tx_ctx ;
856861 uint16_t src_addr = canbus_get_src_lladdr (pkt );
857862 enum net_verdict ret ;
863+ struct net_if * iface = net_pkt_iface (pkt );
864+ struct canbus_net_ctx * net_ctx = net_if_l2_data (iface );
858865
859866 tx_ctx = canbus_get_tx_ctx (NET_CAN_TX_STATE_WAIT_FC , src_addr );
860867 if (!tx_ctx ) {
@@ -865,7 +872,7 @@ static enum net_verdict canbus_process_fc(struct net_pkt *pkt)
865872
866873 ret = canbus_process_fc_data (tx_ctx , pkt );
867874 if (ret == NET_OK ) {
868- k_work_submit_to_queue ( & net_canbus_workq , & tx_ctx -> pkt -> work );
875+ submit_to_queue ( & net_ctx -> tx_queue , tx_ctx -> pkt );
869876 }
870877
871878 return ret ;
@@ -982,8 +989,10 @@ static void canbus_start_sending_cf(struct _timeout *t)
982989{
983990 struct canbus_isotp_tx_ctx * ctx =
984991 CONTAINER_OF (t , struct canbus_isotp_tx_ctx , timeout );
992+ struct net_if * iface = net_pkt_iface (ctx -> pkt );
993+ struct canbus_net_ctx * net_ctx = net_if_l2_data (iface );
985994
986- k_work_submit_to_queue ( & net_canbus_workq , & ctx -> pkt -> work );
995+ submit_to_queue ( & net_ctx -> tx_queue , ctx -> pkt );
987996}
988997
989998static int canbus_send_multiple_frames (struct net_pkt * pkt , size_t len ,
@@ -1008,8 +1017,6 @@ static int canbus_send_multiple_frames(struct net_pkt *pkt, size_t len,
10081017 tx_ctx -> rem_len = net_pkt_get_len (pkt );
10091018 tx_ctx -> tx_backlog = 0 ;
10101019
1011- k_work_init (& pkt -> work , canbus_tx_work_handler );
1012-
10131020 ret = canbus_send_ff (pkt , len , mcast , dest_addr );
10141021 if (ret != CAN_TX_OK ) {
10151022 NET_ERR ("Failed to send FF [%d]" , ret );
@@ -1708,10 +1715,51 @@ static inline int canbus_init_ll_addr(struct net_if *iface)
17081715 return ret ;
17091716}
17101717
1718+ static void queue_handler (struct canbus_net_ctx * ctx )
1719+ {
1720+ struct k_poll_event events [] = {
1721+ K_POLL_EVENT_INITIALIZER (K_POLL_TYPE_FIFO_DATA_AVAILABLE ,
1722+ K_POLL_MODE_NOTIFY_ONLY ,
1723+ & ctx -> tx_queue ),
1724+ K_POLL_EVENT_INITIALIZER (K_POLL_TYPE_FIFO_DATA_AVAILABLE ,
1725+ K_POLL_MODE_NOTIFY_ONLY ,
1726+ & ctx -> rx_err_queue ),
1727+ };
1728+
1729+ struct net_pkt * pkt ;
1730+ int ret ;
1731+
1732+ while (1 ) {
1733+ ret = k_poll (events , ARRAY_SIZE (events ), K_FOREVER );
1734+ if (ret ) {
1735+ continue ;
1736+ }
1737+
1738+ if (events [0 ].state == K_POLL_STATE_FIFO_DATA_AVAILABLE ) {
1739+ pkt = k_fifo_get (& ctx -> tx_queue , K_NO_WAIT );
1740+ if (pkt != NULL ) {
1741+ canbus_tx_work (pkt );
1742+ }
1743+
1744+ events [0 ].state = K_POLL_STATE_NOT_READY ;
1745+ }
1746+
1747+ if (events [1 ].state == K_POLL_STATE_FIFO_DATA_AVAILABLE ) {
1748+ pkt = k_fifo_get (& ctx -> rx_err_queue , K_NO_WAIT );
1749+ if (pkt != NULL ) {
1750+ rx_err_work_handler (pkt );
1751+ }
1752+
1753+ events [1 ].state = K_POLL_STATE_NOT_READY ;
1754+ }
1755+ }
1756+ }
1757+
17111758void net_6locan_init (struct net_if * iface )
17121759{
17131760 struct canbus_net_ctx * ctx = net_if_l2_data (iface );
17141761 int thread_priority ;
1762+ k_tid_t tid ;
17151763 int i ;
17161764
17171765 NET_DBG ("Init CAN net interface" );
@@ -1746,6 +1794,30 @@ void net_6locan_init(struct net_if *iface)
17461794 thread_priority , NULL );
17471795 k_thread_name_set (& net_canbus_workq .thread , "isotp_work" );
17481796 NET_DBG ("Workq started. Thread ID: %p" , & net_canbus_workq .thread );
1797+
1798+ k_fifo_init (& ctx -> tx_queue );
1799+ k_fifo_init (& ctx -> rx_err_queue );
1800+
1801+ tid = k_thread_create (& ctx -> queue_handler , ctx -> queue_stack ,
1802+ K_KERNEL_STACK_SIZEOF (ctx -> queue_stack ),
1803+ (k_thread_entry_t )queue_handler ,
1804+ ctx , NULL , NULL ,
1805+ thread_priority , 0 , K_FOREVER );
1806+ if (!tid ) {
1807+ NET_ERR ("Cannot create queue handler thread for %d" ,
1808+ net_if_get_by_iface (iface ));
1809+ } else {
1810+ if (IS_ENABLED (CONFIG_THREAD_NAME )) {
1811+ #define MAX_NAME_LEN sizeof("isotp[01]")
1812+ char name [MAX_NAME_LEN ];
1813+
1814+ snprintk (name , sizeof (name ), "isotp[%d]" ,
1815+ net_if_get_by_iface (iface ));
1816+ k_thread_name_set (tid , name );
1817+ }
1818+
1819+ k_thread_start (tid );
1820+ }
17491821}
17501822
17511823static int canbus_enable (struct net_if * iface , bool state )
0 commit comments