sdio_enable_func failed in brcmfmac

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
UGMa_1529436
Level 2
Level 2
First like received

We had a wierd problem with brcmfmac driver on our custom board based on Rockchip 3328 and Ampak AP6536s wifi/bt combo.

We are using mainline kernel (4.19). Each time when board is powered on for the first time (aka, cold boot), the brcmfmac driver fails. But if the board is rebooted with linux reboot command (warm boot), then the driver works flawless.

Here is the debug log after cold boot:

[   57.027179] brcmfmac: brcmfmac_module_init No platform data available.

[   57.028082] brcmfmac: brcmf_sdio_probe Enter

[   57.028591] brcmfmac: F1 signature read @0x18000000=0x17224356

[   57.029118] brcmfmac: brcmf_chip_recognition found AXI chip: BCM4356/2

[   57.035575] brcmfmac: brcmf_chip_cores_check  [1 ] core 0x800:47 base 0x18000000 wrap 0x18100000

[   57.035587] brcmfmac: brcmf_chip_cores_check  [2 ] core 0x812:48 base 0x18001000 wrap 0x18101000

[   57.035595] brcmfmac: brcmf_chip_cores_check  [3 ] core 0x83e:6  base 0x18002000 wrap 0x18102000

[   57.035602] brcmfmac: brcmf_chip_cores_check  [4 ] core 0x83c:11 base 0x18003000 wrap 0x18103000

[   57.035610] brcmfmac: brcmf_chip_cores_check  [5 ] core 0x81a:22 base 0x18004000 wrap 0x18104000

[   57.035617] brcmfmac: brcmf_chip_cores_check  [6 ] core 0x829:21 base 0x18005000 wrap 0x18105000

[   57.035625] brcmfmac: brcmf_chip_cores_check  [7 ] core 0x83d:2  base 0x18006000 wrap 0x18106000

[   57.035632] brcmfmac: brcmf_chip_cores_check  [8 ] core 0x135:0  base 0x00000000 wrap 0x1810a000

[   57.035639] brcmfmac: brcmf_chip_cores_check  [9 ] core 0x240:0  base 0x00000000 wrap 0x00000000

[   57.035643] brcmfmac: brcmf_chip_set_passive Enter

[   57.038660] brcmfmac: brcmf_chip_get_raminfo RAM: base=0x180000 size=786432 (0xc0000) sr=0 (0x0)

[   57.038819] brcmfmac: brcmf_chip_setup ccrev=47, pmurev=24, pmucaps=0x420e5f18

[   57.038827] brcmfmac: brcmf_get_module_param Enter, bus=0, chip=17238, rev=2

[   57.038836] brcmfmac: brcmf_sdiod_sgtable_alloc nents=35

[   57.038844] brcmfmac: brcmf_sdio_kso_init Enter

[   57.038897] brcmfmac: brcmf_sdio_drivestrengthinit No SDIO driver strength init needed for chip BCM4356/2 rev 2 pmurev 24

[   57.039410] brcmfmac: brcmf_sdio_probe completed!!

[   57.039422] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2

[   57.039429] brcmfmac: brcmf_fw_get_firmwares enter: dev=mmc0:0001:1

[   57.039436] brcmfmac: brcmf_fw_request_next_item async request for brcm/brcmfmac4356-sdio.bin

[   57.040633] brcmfmac: brcmf_fw_request_done enter: firmware brcm/brcmfmac4356-sdio.bin found

[   57.040643] brcmfmac: brcmf_fw_request_next_item request for brcm/brcmfmac4356-sdio.txt

[   57.040790] brcmfmac: brcmf_fw_request_next_item firmware brcm/brcmfmac4356-sdio.txt found

[   57.040796] brcmfmac: brcmf_fw_request_nvram_done enter: dev=mmc0:0001:1

[   57.041025] brcmfmac: brcmf_fw_request_nvram_done nvram 000000005176650a len 2380

[   57.041034] brcmfmac: brcmf_sdio_firmware_callback Enter: dev=mmc0:0001:1, err=0

[   57.041446] brcmfmac: brcmf_sdio_download_code_file Enter

[   57.397423] brcmfmac: brcmf_sdio_verifymemory Compare RAM dl & ul at 0x00180000; size=526383

[   57.725983] brcmfmac: brcmf_sdio_download_nvram Enter

[   57.727828] brcmfmac: brcmf_sdio_verifymemory Compare RAM dl & ul at 0x0023f6b4; size=2380

[   57.729391] brcmfmac: brcmf_chip_set_active Enter

[   60.733512] brcmfmac: brcmf_sdio_firmware_callback enable F2: err=-62   <------- ERROR

[   60.733596] brcmfmac: brcmf_sdio_firmware_callback failed: dev=mmc0:0001:1, err=-62

[   60.733672] brcmfmac: brcmf_sdio_remove Enter

[   60.733704] brcmfmac: brcmf_detach Enter

[   60.761491] brcmfmac: brcmf_chip_set_passive Enter

[   60.762970] brcmfmac: brcmf_sdio_remove Disconnected

Error occurs when trying to enable func2, right after firmware download. `sdio_enable_func` in `drivers/mmc/core/sdio_io.c` returns ETIME (62).

On this board sdio clock is reduced to 12-20M for debugging. Some sdio pcb routing and signal integrity quirks are found, but I don't think that is related because: 1 firmware download always succeeded with verification; 2 the driver works and the network transmission is stable after a warm reboot.

I cannot image the reason behind the scene. There is no separate dedicated reset signal for the module. The cold boot isn't fast, it takes more than 15s to bring up the system.  So everything onboard have enough time to stablize.

I am sure both cold boot and warm boot go throught the same code path, including spl, uboot and kernel. There is no "short-circuited" code during warm boot on this platform.

I also tried blacklist the brcmfmac driver and modprobe it manually. Nothing changed.

On this platform, gmac (eth) and sdio are provided by the same group of pins. In reference design, only gmac/eth is provided, while on our custom board, gmac/eth is removed and the signals are used for sdio wifi/bt combo instead. In kernel dts, all gmac related nodes are removed out of dts. In u-boot, the ethernet boot code remains. So there is a little chance that those code influenced the combo module behavior. However, such code is also executed during warm boot. I am going to disable gmac related code in u-boot to see if it is the cause of the problem. Also I want to here your advice to figure out the root cause.

Here is the device tree configuration

  8

  9 / {

...

18   sdio_pwrseq: sdio-pwrseq {

19     compatible = "mmc-pwrseq-simple";

20     pinctrl-names = "default";

21     pinctrl-0 = <&wifi_enable_h>;

22

23     /*

24      * On the module itself this is one of these (depending

25      * on the actual card populated):

26      * - SDIO_RESET_L_WL_REG_ON

27      * - PDN (power down when low)

28      */

29     reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;

30   };

...

98 &sdio {

99   bus-width = <4>;

100   cap-sd-highspeed;

101   cap-sdio-irq;

102   keep-power-in-suspend;

103   max-frequency = <20000000>;

104   mmc-pwrseq = <&sdio_pwrseq>;

105   non-removable;

106   pinctrl-names = "default";

107   pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;

108   status = "okay";

109

110   brcmf: wifi@1 {

111     compatible = "brcm,bcm4329-fmac";

112     interrupt-parent = <&gpio1>;

113     interrupts = <RK_PC3 GPIO_ACTIVE_HIGH>;

114     interrupt-names = "host-wake";

115     brcm,drive-strength = <5>;

116     pinctrl-names = "default";

117     pinctrl-0 = <&wifi_host_wake_l>;

118   };

119 };

...

252 &pinctrl {

...

271   sdio_pwrseq {

272     wifi_enable_h: wifi-enable-h {

273     rockchip,pins =

274       <1 18 RK_FUNC_GPIO &pcfg_pull_down>;

275     };

276   };

277

278   wifi {

279     wifi_host_wake_l: wifi-host-wake-l {

280       /** GPIO1_C3 */

281       rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;

282     };

283   };

284 };

0 Likes
1 Solution
UGMa_1529436
Level 2
Level 2
First like received

I am so lucky today. The root cause is found and the problem solved.

Rockchip provides a common clock framework driver for a family of PMICs, including rk805/rk808/rk818 etc. The driver is configured in kernel by CONFIG_COMMON_CLK_RK808.

This driver works for rk808, which is designed for rk3399 platform. At least for Nano PC T4, it works flawless. However, this driver interrupts the clkout from rk805. So the wifi core hangs.

Simply turning off this driver in kernel and the wifi module works all the time, no matter the board is cold booted or warm booted.

View solution in original post

3 Replies
MichaelF_56
Moderator
Moderator
Moderator
250 sign-ins 25 comments on blog 10 comments on blog

Have you reached out to Ampak for support on this issue?

vnak

0 Likes

Not yet. This module is very popular on SBCs from arm/linux community. We have checked schematics from several boards, such as Nano PC T4 from friendlyarm. I can confirm that the hardware wiring of the module is OK.

----

Now I have a little progress, though the problem remains unsolved utterly.Z

If I force a mmc host rescan from userspace after booting into the system, using the following commands:

echo -n "ff510000.dwmmc" > /sys/devices/platform/ff510000.dwmmc/driver/unbind

echo -n "ff510000.dwmmc" > /sys/devices/platform/ff510000.dwmmc/subsystem/drivers/dwmmc_rockchip/bind

then brcmfmac works.

This is tested under the following cases:

1. module is powered at the same time the board is powered on.

2. module is powered around 1s after powering the board but before the kernel start to boot.

3. module is powered after booting into the system.

In all cases, a forceful mmc_rescan resolved the problem.

In the design, 32K clock is provided by pmic, there is a little chance that the kernel pmic driver manipulated the clock signal for a short period and the module fell into an hanging state. I will dig it further in a few days.

0 Likes
UGMa_1529436
Level 2
Level 2
First like received

I am so lucky today. The root cause is found and the problem solved.

Rockchip provides a common clock framework driver for a family of PMICs, including rk805/rk808/rk818 etc. The driver is configured in kernel by CONFIG_COMMON_CLK_RK808.

This driver works for rk808, which is designed for rk3399 platform. At least for Nano PC T4, it works flawless. However, this driver interrupts the clkout from rk805. So the wifi core hangs.

Simply turning off this driver in kernel and the wifi module works all the time, no matter the board is cold booted or warm booted.