@@ -328,6 +328,23 @@ static inline void receive_signal_raise(void)
328328 mpsl_work_submit (& receive_work );
329329}
330330
331+ /** Storage for HCI packets from controller to host */
332+ static struct {
333+ /* Buffer for the HCI packet. */
334+ uint8_t buf [HCI_RX_BUF_SIZE ];
335+ /* Type of the HCI packet the buffer contains. */
336+ sdc_hci_msg_type_t type ;
337+ } rx_hci_msg ;
338+
339+ static void bt_buf_rx_freed_cb (enum bt_buf_type type_mask )
340+ {
341+ if (((rx_hci_msg .type == SDC_HCI_MSG_TYPE_EVT && (type_mask & BT_BUF_EVT ) != 0u ) ||
342+ (rx_hci_msg .type == SDC_HCI_MSG_TYPE_DATA && (type_mask & BT_BUF_ACL_IN ) != 0u ) ||
343+ (rx_hci_msg .type == SDC_HCI_MSG_TYPE_ISO && (type_mask & BT_BUF_ISO_IN ) != 0u ))) {
344+ receive_signal_raise ();
345+ }
346+ }
347+
331348static int cmd_handle (struct net_buf * cmd )
332349{
333350 LOG_DBG ("" );
@@ -429,16 +446,16 @@ static int hci_driver_send(const struct device *dev, struct net_buf *buf)
429446 return err ;
430447}
431448
432- static void data_packet_process (const struct device * dev , uint8_t * hci_buf )
449+ static int data_packet_process (const struct device * dev , uint8_t * hci_buf )
433450{
434- struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_FOREVER );
451+ struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ACL_IN , K_NO_WAIT );
435452 struct bt_hci_acl_hdr * hdr = (void * )hci_buf ;
436453 uint16_t hf , handle , len ;
437454 uint8_t flags , pb , bc ;
438455
439456 if (!data_buf ) {
440- LOG_ERR ("No data buffer available" );
441- return ;
457+ LOG_DBG ("No data buffer available" );
458+ return - ENOBUFS ;
442459 }
443460
444461 len = sys_le16_to_cpu (hdr -> len );
@@ -452,8 +469,7 @@ static void data_packet_process(const struct device *dev, uint8_t *hci_buf)
452469 LOG_ERR ("Event buffer too small. %u > %u" ,
453470 len + sizeof (* hdr ),
454471 HCI_RX_BUF_SIZE );
455- k_panic ();
456- return ;
472+ return - ENOMEM ;
457473 }
458474
459475 LOG_DBG ("Data: handle (0x%02x), PB(%01d), BC(%01d), len(%u)" , handle ,
@@ -464,28 +480,36 @@ static void data_packet_process(const struct device *dev, uint8_t *hci_buf)
464480 struct hci_driver_data * driver_data = dev -> data ;
465481
466482 driver_data -> recv_func (dev , data_buf );
483+
484+ return 0 ;
467485}
468486
469- static void iso_data_packet_process (const struct device * dev , uint8_t * hci_buf )
487+ static int iso_data_packet_process (const struct device * dev , uint8_t * hci_buf )
470488{
471- struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ISO_IN , K_FOREVER );
489+ struct net_buf * data_buf = bt_buf_get_rx (BT_BUF_ISO_IN , K_NO_WAIT );
472490 struct bt_hci_iso_hdr * hdr = (void * )hci_buf ;
473491
474492 uint16_t len = sys_le16_to_cpu (hdr -> len );
475493
494+ if (!data_buf ) {
495+ LOG_DBG ("No data buffer available" );
496+ return - ENOBUFS ;
497+ }
498+
476499 if (len + sizeof (* hdr ) > HCI_RX_BUF_SIZE ) {
477500 LOG_ERR ("Event buffer too small. %u > %u" ,
478501 len + sizeof (* hdr ),
479502 HCI_RX_BUF_SIZE );
480- k_panic ();
481- return ;
503+ return - ENOMEM ;
482504 }
483505
484506 net_buf_add_mem (data_buf , & hci_buf [0 ], len + sizeof (* hdr ));
485507
486508 struct hci_driver_data * driver_data = dev -> data ;
487509
488- driver_data -> recv_func (dev , data_buf );
510+ (void )driver_data -> recv_func (dev , data_buf );
511+
512+ return 0 ;
489513}
490514
491515static bool event_packet_is_discardable (const uint8_t * hci_buf )
@@ -532,7 +556,7 @@ static bool event_packet_is_discardable(const uint8_t *hci_buf)
532556 }
533557}
534558
535- static void event_packet_process (const struct device * dev , uint8_t * hci_buf )
559+ static int event_packet_process (const struct device * dev , uint8_t * hci_buf )
536560{
537561 bool discardable = event_packet_is_discardable (hci_buf );
538562 struct bt_hci_evt_hdr * hdr = (void * )hci_buf ;
@@ -542,8 +566,7 @@ static void event_packet_process(const struct device *dev, uint8_t *hci_buf)
542566 LOG_ERR ("Event buffer too small. %u > %u" ,
543567 hdr -> len + sizeof (* hdr ),
544568 HCI_RX_BUF_SIZE );
545- k_panic ();
546- return ;
569+ return - ENOMEM ;
547570 }
548571
549572 if (hdr -> evt == BT_HCI_EVT_LE_META_EVENT ) {
@@ -569,67 +592,85 @@ static void event_packet_process(const struct device *dev, uint8_t *hci_buf)
569592 LOG_DBG ("Event (0x%02x) len %u" , hdr -> evt , hdr -> len );
570593 }
571594
572- evt_buf = bt_buf_get_evt (hdr -> evt , discardable ,
573- discardable ? K_NO_WAIT : K_FOREVER );
595+ evt_buf = bt_buf_get_evt (hdr -> evt , discardable , K_NO_WAIT );
574596
575597 if (!evt_buf ) {
576598 if (discardable ) {
577599 LOG_DBG ("Discarding event" );
578- return ;
600+ return 0 ;
579601 }
580602
581- LOG_ERR ("No event buffer available" );
582- return ;
603+ LOG_DBG ("No event buffer available" );
604+ return - ENOBUFS ;
583605 }
584606
585607 net_buf_add_mem (evt_buf , & hci_buf [0 ], hdr -> len + sizeof (* hdr ));
586608
587609 struct hci_driver_data * driver_data = dev -> data ;
588610
589- driver_data -> recv_func (dev , evt_buf );
611+ (void )driver_data -> recv_func (dev , evt_buf );
612+
613+ return 0 ;
590614}
591615
592- static bool fetch_and_process_hci_msg ( const struct device * dev , uint8_t * p_hci_buffer )
616+ static int fetch_hci_msg ( uint8_t * p_hci_buffer , sdc_hci_msg_type_t * msg_type )
593617{
594618 int errcode ;
595- sdc_hci_msg_type_t msg_type ;
596619
597620 errcode = MULTITHREADING_LOCK_ACQUIRE ();
598621 if (!errcode ) {
599- errcode = hci_internal_msg_get (p_hci_buffer , & msg_type );
622+ errcode = hci_internal_msg_get (p_hci_buffer , msg_type );
600623 MULTITHREADING_LOCK_RELEASE ();
601624 }
602625
603- if (errcode ) {
604- return false;
605- }
626+ return errcode ;
627+ }
628+
629+ static int process_hci_msg (const struct device * dev , uint8_t * p_hci_buffer ,
630+ sdc_hci_msg_type_t msg_type )
631+ {
632+ int err ;
606633
607634 if (msg_type == SDC_HCI_MSG_TYPE_EVT ) {
608- event_packet_process (dev , p_hci_buffer );
635+ err = event_packet_process (dev , p_hci_buffer );
609636 } else if (msg_type == SDC_HCI_MSG_TYPE_DATA ) {
610- data_packet_process (dev , p_hci_buffer );
637+ err = data_packet_process (dev , p_hci_buffer );
611638 } else if (msg_type == SDC_HCI_MSG_TYPE_ISO ) {
612- iso_data_packet_process (dev , p_hci_buffer );
639+ err = iso_data_packet_process (dev , p_hci_buffer );
613640 } else {
614641 if (!IS_ENABLED (CONFIG_BT_CTLR_SDC_SILENCE_UNEXPECTED_MSG_TYPE )) {
615642 LOG_ERR ("Unexpected msg_type: %u. This if-else needs a new branch" ,
616643 msg_type );
617644 }
645+ err = 0 ;
618646 }
619647
620- return true ;
648+ return err ;
621649}
622650
623651void hci_driver_receive_process (void )
624652{
625- static uint8_t hci_buf [HCI_RX_BUF_SIZE ];
626-
627653 const struct device * dev = DEVICE_DT_GET (DT_DRV_INST (0 ));
654+ int err ;
628655
629- if (fetch_and_process_hci_msg (dev , & hci_buf [0 ])) {
630- /* Let other threads of same priority run in between. */
631- receive_signal_raise ();
656+ if (rx_hci_msg .type == SDC_HCI_MSG_TYPE_NONE &&
657+ fetch_hci_msg (& rx_hci_msg .buf [0 ], & rx_hci_msg .type ) != 0 ) {
658+ return ;
659+ }
660+
661+ err = process_hci_msg (dev , & rx_hci_msg .buf [0 ], rx_hci_msg .type );
662+ if (err == - ENOBUFS ) {
663+ /* If we got -ENOBUFS, wait for the signal from the host. */
664+ return ;
665+ } else if (err ) {
666+ LOG_ERR ("Unknown error when processing hci message %d" , err );
667+ k_panic ();
632668 }
669+
670+ rx_hci_msg .type = SDC_HCI_MSG_TYPE_NONE ;
671+
672+ /* Let other threads of same priority run in between. */
673+ receive_signal_raise ();
633674}
634675
635676static void receive_work_handler (struct k_work * work )
@@ -1410,6 +1451,8 @@ static int hci_driver_open(const struct device *dev, bt_hci_recv_t recv_func)
14101451
14111452 driver_data -> recv_func = recv_func ;
14121453
1454+ bt_buf_rx_freed_cb_set (bt_buf_rx_freed_cb );
1455+
14131456 return 0 ;
14141457}
14151458
@@ -1442,6 +1485,8 @@ static int hci_driver_close(const struct device *dev)
14421485
14431486 MULTITHREADING_LOCK_RELEASE ();
14441487
1488+ bt_buf_rx_freed_cb_set (NULL );
1489+
14451490 return err ;
14461491}
14471492
0 commit comments