-
Notifications
You must be signed in to change notification settings - Fork 8.1k
drivers: entropy: Fix non-stop RNG ISR firing for STM32WB09 #98151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Fix the TRNG driver issue regarding non-stop ISR firing for STM32WB09. Clear RNG_IRQ_SR_ERROR_IRQ and RNG_IRQ_SR_FF_FULL_IRQ flags when they are set. Change the number of attempts to empty the RNG FIFO according to its size. Signed-off-by: Ali Hozhabri <[email protected]>
…ance Fix the issue regarding passing the TRNG peripheral instance to the driver. Increase the SYSTEM_WORKQUEUE_STACK_SIZE when CONFIG_BT is set. Signed-off-by: Ali Hozhabri <[email protected]>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how "drivers: entropy: Fix non-stop RNG ISR firing for STM32WB09" fixes your issue. I must miss something if it really changes the driver behavior.
For commit "drivers: bluetooth: hci: Fix the issue about the TRNG peripheral instance": could you describe a bit more why CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE is increased: how does it help? I also this the commit message header line and body is not very explicit about which TRNG issue is being addressed.
| */ | ||
| WRITE_REG(RNG->IRQ_SR, RNG_IRQ_SR_FF_FULL_IRQ); | ||
| if (LL_RNG_GetFfFullIrq(RNGx)) { | ||
| SET_BIT(RNGx->IRQ_SR, RNG_IRQ_SR_FF_FULL_IRQ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using SET_BIT(), you may clear also a pending ERROR flag. I think WRITE_REG() was the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1: WRITE_REG is the correct operation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you're saying is the opposite. As the name suggests, SET_BIT() is for setting one bit of the register, while WRITE_REG() manipulates the whole register. Here you can find these two macros as follows:
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know what the macros do. SET_BIT() is not correct here because it does a read then write, and the flags are cleared by writing 1 to their bit:

If ERROR_IRQ was 1, SET_BIT(IRQ_SR, FF_FULL_IRQ) will read the register (= ERROR_IRQ), then |= FF_FULL_IRQ to the read value and write back the result (= ERROR_IRQ | FF_FULL_IRQ) which will clear both interrupt flags.
Using WRITE_REG (or really, just RNG->IRQ_SR = RNG_IRQ_SR_FF_FULL_IRQ) will write a value with only bit FF_FULL_IRQ set which ensures that only this specific interrupt flag is cleared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I understand, thanks for the clarification.
|
|
||
| #if defined(CONFIG_SOC_STM32WB09XX) | ||
| if (LL_RNG_GetErrorIrq(rng)) { | ||
| SET_BIT(rng->IRQ_SR, RNG_IRQ_SR_ERROR_IRQ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flag should have already been cleared by ll_rng_clear_sei() above.
Using SET_BIT() here may also clear the FF_FULL flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ll_rng_clear_seis() doesn't clear IRQ_SR_ERROR 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etienne-lms , ll_rng_clear_seis() clears RNG_CR_RST_HEALTH_FLAGS flag.
For your second sentence, please refer to the previous comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake. Indeed it is an error, we should clear that bit.
Could you rather fix ll_rng_clear_sei() adding their clear of IRQ_SR_ERROR?
I think we need to revisit a bit WB09xx sequences in this driver.
| #if IRQLESS_TRNG | ||
| #define MAX_AVAIL_RND_NUM 1 | ||
| #else | ||
| #define MAX_AVAIL_RND_NUM 4 /* Internal four-word FIFO */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an error is triggered only 3 samples are to be removed from the 4-word FIFO.
If there is no FIFO, there is nothing to evacuate since upon error RNG produces no random sample.
That said, the change shows something that was not update by commit d65f8e3: indeed value 12 should have been updated to 3 at that time and no-FIFO instance addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't really matter, reading empty FIFO will just return 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And FWIW other IPs do also have a FIFO but no corresponding "FIFO full" interrupt so I'm not sure that lowering this value is "correct"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think lowering the value will fix anything. Just a matter of consistency.
| } | ||
|
|
||
| #if defined(CONFIG_SOC_STM32WB09XX) | ||
| if (LL_RNG_GetErrorIrq(rng)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on Etienne's comment: unless there's a reason for it, let's not bother checking for the flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean clearing a flag without checking if it is raised?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Per RefMan, this should have no effect
| */ | ||
| WRITE_REG(RNG->IRQ_SR, RNG_IRQ_SR_FF_FULL_IRQ); | ||
| if (LL_RNG_GetFfFullIrq(RNGx)) { | ||
| SET_BIT(RNGx->IRQ_SR, RNG_IRQ_SR_FF_FULL_IRQ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1: WRITE_REG is the correct operation
| ll_rng_clear_seis(rng); | ||
|
|
||
| for (int i = 0; i < 12; ++i) { | ||
| for (int i = 0; i < MAX_AVAIL_RND_NUM; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be replaced with:
| for (int i = 0; i < MAX_AVAIL_RND_NUM; ++i) { | |
| while (ll_rng_is_active_drdy(rng)) { |
to be more solid
| config SYSTEM_WORKQUEUE_STACK_SIZE | ||
| default 1152 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| config SYSTEM_WORKQUEUE_STACK_SIZE | |
| default 1152 | |
| configdefault SYSTEM_WORKQUEUE_STACK_SIZE | |
| default 1152 |
Clearing the interrupt flags prevents continuous interrupt firing.
In this commit, the correct node identifier of RNG is passed to the variable. Previously, it was |
Ok, I understand now that you pointed me
Ok. Right, you mention that in the commit message body.
Could you mention that in the commit message? Like |
|
|
||
| #if defined(CONFIG_SOC_STM32WB09XX) | ||
| if (LL_RNG_GetErrorIrq(rng)) { | ||
| SET_BIT(rng->IRQ_SR, RNG_IRQ_SR_ERROR_IRQ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use new bits handling functions: #97329



Fix the TRNG driver issue regarding non-stop ISR firing for STM32WB09.
Clear RNG_IRQ_SR_ERROR_IRQ and RNG_IRQ_SR_FF_FULL_IRQ flags when they are set.
Change the number of attempts to empty the RNG FIFO according to the FIFO size.
Fix the issue regarding passing the TRNG peripheral instance to the BLE driver.
Increase the SYSTEM_WORKQUEUE_STACK_SIZE when CONFIG_BT is set.
Here is the screenshot of
beaconsample to show the reason for increasingSYSTEM_WORKQUEUE_STACK_SIZE. Previously, the default was 1024 bytes.