Skip to content

Commit 348e0b9

Browse files
Merge branch 'nrfconnect:main' into gdservices
2 parents 4b833ce + f4cb303 commit 348e0b9

35 files changed

+858
-66
lines changed

doc/releases/release-notes-4.0.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ Bluetooth
107107

108108
* HCI Drivers
109109

110+
* Mesh
111+
112+
* Introduced a mesh-specific workqueue to increase reliability of the mesh messages
113+
transmission. To get the old behavior enable :kconfig:option:`CONFIG_BT_MESH_WORKQ_SYS`.
114+
110115
Boards & SoC Support
111116
********************
112117

drivers/usb/udc/udc_dwc2.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,11 @@ enum dwc2_drv_event_type {
5454
*/
5555
#define UDC_DWC2_GRXFSIZ_HS_DEFAULT (13 + 1 + 774)
5656

57-
/* TX FIFO0 depth in 32-bit words (used by control IN endpoint) */
58-
#define UDC_DWC2_FIFO0_DEPTH 16U
57+
/* TX FIFO0 depth in 32-bit words (used by control IN endpoint)
58+
* Try 2 * bMaxPacketSize0 to allow simultaneous operation with a fallback to
59+
* whatever is available when 2 * bMaxPacketSize0 is not possible.
60+
*/
61+
#define UDC_DWC2_FIFO0_DEPTH (2 * 16U)
5962

6063
/* Get Data FIFO access register */
6164
#define UDC_DWC2_EP_FIFO(base, idx) ((mem_addr_t)base + 0x1000 * (idx + 1))
@@ -99,9 +102,9 @@ struct udc_dwc2_data {
99102
struct k_thread thread_data;
100103
/* Main events the driver thread waits for */
101104
struct k_event drv_evt;
102-
/* Transfer triggers (OUT on bits 0-15, IN on bits 16-31) */
105+
/* Transfer triggers (IN on bits 0-15, OUT on bits 16-31) */
103106
struct k_event xfer_new;
104-
/* Finished transactions (OUT on bits 0-15, IN on bits 16-31) */
107+
/* Finished transactions (IN on bits 0-15, OUT on bits 16-31) */
105108
struct k_event xfer_finished;
106109
struct dwc2_reg_backup backup;
107110
uint32_t ghwcfg1;
@@ -1184,7 +1187,7 @@ static int dwc2_set_dedicated_fifo(const struct device *dev,
11841187
dwc2_get_txfaddr(dev, ep_idx - 2);
11851188
} else {
11861189
txfaddr = priv->rxfifo_depth +
1187-
MAX(UDC_DWC2_FIFO0_DEPTH, priv->max_txfifo_depth[0]);
1190+
MIN(UDC_DWC2_FIFO0_DEPTH, priv->max_txfifo_depth[0]);
11881191
}
11891192

11901193
/* Make sure to not set TxFIFO greater than hardware allows */
@@ -1554,9 +1557,9 @@ static int udc_dwc2_ep_clear_halt(const struct device *dev,
15541557
uint32_t ep_bit;
15551558

15561559
if (USB_EP_DIR_IS_IN(cfg->addr)) {
1557-
ep_bit = BIT(16 + USB_EP_GET_IDX(cfg->addr));
1558-
} else {
15591560
ep_bit = BIT(USB_EP_GET_IDX(cfg->addr));
1561+
} else {
1562+
ep_bit = BIT(16 + USB_EP_GET_IDX(cfg->addr));
15601563
}
15611564

15621565
k_event_post(&priv->xfer_new, ep_bit);
@@ -1579,9 +1582,9 @@ static int udc_dwc2_ep_enqueue(const struct device *dev,
15791582
uint32_t ep_bit;
15801583

15811584
if (USB_EP_DIR_IS_IN(cfg->addr)) {
1582-
ep_bit = BIT(16 + USB_EP_GET_IDX(cfg->addr));
1583-
} else {
15841585
ep_bit = BIT(USB_EP_GET_IDX(cfg->addr));
1586+
} else {
1587+
ep_bit = BIT(16 + USB_EP_GET_IDX(cfg->addr));
15851588
}
15861589

15871590
k_event_post(&priv->xfer_new, ep_bit);
@@ -1939,7 +1942,7 @@ static int udc_dwc2_init_controller(const struct device *dev)
19391942
sys_write32(usb_dwc2_set_grxfsiz(priv->rxfifo_depth), grxfsiz_reg);
19401943

19411944
/* Set TxFIFO 0 depth */
1942-
val = MAX(UDC_DWC2_FIFO0_DEPTH, priv->max_txfifo_depth[0]);
1945+
val = MIN(UDC_DWC2_FIFO0_DEPTH, priv->max_txfifo_depth[0]);
19431946
gnptxfsiz = usb_dwc2_set_gnptxfsiz_nptxfdep(val) |
19441947
usb_dwc2_set_gnptxfsiz_nptxfstaddr(priv->rxfifo_depth);
19451948

@@ -2346,7 +2349,7 @@ static inline void dwc2_handle_in_xfercompl(const struct device *dev,
23462349
return;
23472350
}
23482351

2349-
k_event_post(&priv->xfer_finished, BIT(16 + ep_idx));
2352+
k_event_post(&priv->xfer_finished, BIT(ep_idx));
23502353
k_event_post(&priv->drv_evt, BIT(DWC2_DRV_EVT_EP_FINISHED));
23512354
}
23522355

@@ -2452,7 +2455,7 @@ static inline void dwc2_handle_out_xfercompl(const struct device *dev,
24522455
net_buf_tailroom(buf)) {
24532456
dwc2_prep_rx(dev, buf, ep_cfg);
24542457
} else {
2455-
k_event_post(&priv->xfer_finished, BIT(ep_idx));
2458+
k_event_post(&priv->xfer_finished, BIT(16 + ep_idx));
24562459
k_event_post(&priv->drv_evt, BIT(DWC2_DRV_EVT_EP_FINISHED));
24572460
}
24582461
}
@@ -2803,9 +2806,9 @@ static uint8_t pull_next_ep_from_bitmap(uint32_t *bitmap)
28032806
*bitmap &= ~BIT(bit);
28042807

28052808
if (bit >= 16) {
2806-
return USB_EP_DIR_IN | (bit - 16);
2809+
return USB_EP_DIR_OUT | (bit - 16);
28072810
} else {
2808-
return USB_EP_DIR_OUT | bit;
2811+
return USB_EP_DIR_IN | bit;
28092812
}
28102813
}
28112814

drivers/usb/udc/udc_nrf.c

Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ static struct k_thread drv_stack_data;
7070

7171
static struct udc_ep_config ep_cfg_out[CFG_EPOUT_CNT + CFG_EP_ISOOUT_CNT + 1];
7272
static struct udc_ep_config ep_cfg_in[CFG_EPIN_CNT + CFG_EP_ISOIN_CNT + 1];
73-
static bool udc_nrf_setup_rcvd;
73+
static bool udc_nrf_setup_rcvd, udc_nrf_setup_set_addr, udc_nrf_fake_setup;
74+
static uint8_t udc_nrf_address;
7475
const static struct device *udc_nrf_dev;
7576

7677
struct udc_nrf_config {
@@ -143,7 +144,9 @@ static void udc_event_xfer_ctrl_in(const struct device *dev,
143144
/* Update to next stage of control transfer */
144145
udc_ctrl_update_stage(dev, buf);
145146

146-
nrf_usbd_common_setup_clear();
147+
if (!udc_nrf_setup_set_addr) {
148+
nrf_usbd_common_setup_clear();
149+
}
147150
}
148151

149152
static void udc_event_fake_status_in(const struct device *dev)
@@ -317,6 +320,7 @@ static int usbd_ctrl_feed_dout(const struct device *dev,
317320

318321
static int udc_event_xfer_setup(const struct device *dev)
319322
{
323+
nrf_usbd_common_setup_t *setup;
320324
struct net_buf *buf;
321325
int err;
322326

@@ -328,7 +332,77 @@ static int udc_event_xfer_setup(const struct device *dev)
328332
}
329333

330334
udc_ep_buf_set_setup(buf);
331-
nrf_usbd_common_setup_get((nrf_usbd_common_setup_t *)buf->data);
335+
setup = (nrf_usbd_common_setup_t *)buf->data;
336+
nrf_usbd_common_setup_get(setup);
337+
338+
/* USBD peripheral automatically handles Set Address in slightly
339+
* different manner than the USB stack.
340+
*
341+
* USBD peripheral doesn't care about wLength, but the peripheral
342+
* switches to new address only after status stage. The device won't
343+
* automatically accept Data Stage packets.
344+
*
345+
* However, in the case the host:
346+
* * sends SETUP Set Address with non-zero wLength
347+
* * does not send corresponding OUT DATA packets (to match wLength)
348+
* or sends the packets but disregards NAK
349+
* or sends the packets that device ACKs
350+
* * sends IN token (either incorrectly proceeds to status stage, or
351+
* manages to send IN before SW sets STALL)
352+
* then the USBD peripheral will accept the address and USB stack won't.
353+
* This will lead to state mismatch between the stack and peripheral.
354+
*
355+
* In cases where the USB stack would like to STALL the request there is
356+
* a race condition between host issuing Set Address status stage (IN
357+
* token) and SW setting STALL bit. If host wins the race, the device
358+
* ACKs status stage and use new address. If device wins the race, the
359+
* device STALLs status stage and address remains unchanged.
360+
*/
361+
udc_nrf_setup_set_addr =
362+
setup->bmRequestType == 0 &&
363+
setup->bRequest == USB_SREQ_SET_ADDRESS;
364+
if (udc_nrf_setup_set_addr) {
365+
if (setup->wLength) {
366+
/* Currently USB stack only STALLs OUT Data Stage when
367+
* buffer allocation fails. To prevent the device from
368+
* ACKing the Data Stage, simply ignore the request
369+
* completely.
370+
*
371+
* If host incorrectly proceeds to status stage there
372+
* will be address mismatch (unless the new address is
373+
* equal to current device address). If host does not
374+
* issue IN token then the mismatch will be avoided.
375+
*/
376+
net_buf_unref(buf);
377+
return 0;
378+
}
379+
380+
/* nRF52/nRF53 USBD doesn't care about wValue bits 8..15 and
381+
* wIndex value but USB device stack does.
382+
*
383+
* Just clear the bits so stack will handle the request in the
384+
* same way as USBD peripheral does, avoiding the mismatch.
385+
*/
386+
setup->wValue &= 0x7F;
387+
setup->wIndex = 0;
388+
}
389+
390+
if (!udc_nrf_setup_set_addr && udc_nrf_address != NRF_USBD->USBADDR) {
391+
/* Address mismatch detected. Fake Set Address handling to
392+
* correct the situation, then repeat handling.
393+
*/
394+
udc_nrf_fake_setup = true;
395+
udc_nrf_setup_set_addr = true;
396+
397+
setup->bmRequestType = 0;
398+
setup->bRequest = USB_SREQ_SET_ADDRESS;
399+
setup->wValue = NRF_USBD->USBADDR;
400+
setup->wIndex = 0;
401+
setup->wLength = 0;
402+
} else {
403+
udc_nrf_fake_setup = false;
404+
}
405+
332406
net_buf_add(buf, sizeof(nrf_usbd_common_setup_t));
333407
udc_nrf_setup_rcvd = true;
334408

@@ -487,17 +561,21 @@ static void udc_nrf_power_handler(nrfx_power_usb_evt_t pwr_evt)
487561
}
488562
}
489563

490-
static void udc_nrf_fake_status_in(const struct device *dev)
564+
static bool udc_nrf_fake_status_in(const struct device *dev)
491565
{
492566
struct udc_nrf_evt evt = {
493567
.type = UDC_NRF_EVT_STATUS_IN,
494568
.ep = USB_CONTROL_EP_IN,
495569
};
496570

497-
if (nrf_usbd_common_last_setup_dir_get() == USB_CONTROL_EP_OUT) {
571+
if (nrf_usbd_common_last_setup_dir_get() == USB_CONTROL_EP_OUT ||
572+
udc_nrf_fake_setup) {
498573
/* Let controller perform status IN stage */
499574
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
575+
return true;
500576
}
577+
578+
return false;
501579
}
502580

503581
static int udc_nrf_ep_enqueue(const struct device *dev,
@@ -512,8 +590,9 @@ static int udc_nrf_ep_enqueue(const struct device *dev,
512590
udc_buf_put(cfg, buf);
513591

514592
if (cfg->addr == USB_CONTROL_EP_IN && buf->len == 0) {
515-
udc_nrf_fake_status_in(dev);
516-
return 0;
593+
if (udc_nrf_fake_status_in(dev)) {
594+
return 0;
595+
}
517596
}
518597

519598
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
@@ -608,12 +687,38 @@ static int udc_nrf_ep_clear_halt(const struct device *dev,
608687

609688
static int udc_nrf_set_address(const struct device *dev, const uint8_t addr)
610689
{
611-
/**
612-
* Nothing to do here. The USBD HW already takes care of initiating
613-
* STATUS stage. Just double check the address for sanity.
690+
/*
691+
* If the status stage already finished (which depends entirely on when
692+
* the host sends IN token) then NRF_USBD->USBADDR will have the same
693+
* address, otherwise it won't (unless new address is unchanged).
694+
*
695+
* Store the address so the driver can detect address mismatches
696+
* between USB stack and USBD peripheral. The mismatches can occur if:
697+
* * SW has high enough latency in SETUP handling, or
698+
* * Host did not issue Status Stage after Set Address request
699+
*
700+
* The SETUP handling latency is a problem because the Set Address is
701+
* automatically handled by device. Because whole Set Address handling
702+
* can finish in less than 21 us, the latency required (with perfect
703+
* timing) to hit the issue is relatively short (2 ms Set Address
704+
* recovery interval + negligible Set Address handling time). If host
705+
* sends new SETUP before SW had a chance to read the Set Address one,
706+
* the Set Address one will be overwritten without a trace.
614707
*/
615-
if (addr != (uint8_t)NRF_USBD->USBADDR) {
616-
LOG_WRN("USB Address incorrect 0x%02x", addr);
708+
udc_nrf_address = addr;
709+
710+
if (udc_nrf_fake_setup) {
711+
struct udc_nrf_evt evt = {
712+
.type = UDC_NRF_EVT_HAL,
713+
.hal_evt = {
714+
.type = NRF_USBD_COMMON_EVT_SETUP,
715+
},
716+
};
717+
718+
/* Finished handling lost Set Address, now handle the pending
719+
* SETUP transfer.
720+
*/
721+
k_msgq_put(&drv_msgq, &evt, K_NO_WAIT);
617722
}
618723

619724
return 0;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
CONFIG_IPC_SERVICE=y
2+
CONFIG_MBOX=y
3+
4+
CONFIG_ISR_STACK_SIZE=1024
5+
CONFIG_IDLE_STACK_SIZE=256
6+
CONFIG_MAIN_STACK_SIZE=512
7+
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512
8+
CONFIG_IPC_SERVICE_BACKEND_RPMSG_WQ_STACK_SIZE=512
9+
CONFIG_HEAP_MEM_POOL_SIZE=8192
10+
11+
CONFIG_BT=y
12+
CONFIG_BT_HCI_RAW=y
13+
14+
CONFIG_BT_BUF_EVT_RX_COUNT=16
15+
CONFIG_BT_BUF_EVT_RX_SIZE=255
16+
CONFIG_BT_BUF_ACL_RX_SIZE=255
17+
CONFIG_BT_BUF_ACL_TX_SIZE=251
18+
CONFIG_BT_BUF_CMD_TX_SIZE=255
19+
20+
# Host
21+
CONFIG_BT_BROADCASTER=y
22+
CONFIG_BT_PERIPHERAL=y
23+
CONFIG_BT_OBSERVER=y
24+
CONFIG_BT_CENTRAL=y
25+
CONFIG_BT_EXT_ADV=y
26+
CONFIG_BT_PER_ADV=y
27+
CONFIG_BT_PER_ADV_SYNC=y
28+
29+
# Controller
30+
CONFIG_BT_LL_SW_SPLIT=n
31+
CONFIG_BT_LL_SOFTDEVICE=y
32+
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
33+
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=191

0 commit comments

Comments
 (0)