brcmfamc - OMAP SG entry not aligned with block size

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

cross mob
Anonymous
Not applicable

Hi Venkat,

I add the below debug print in omap_hsmmc.c.

/* Sanity check: all the SG entries must be aligned by block size. */

        for (i = 0; i < data->sg_len; i++) {

                struct scatterlist *sgl;

                sgl = data->sg + i;

                if (sgl->length % data->blksz){

                        printk("%s Sgl Length %d Data Block Size %d\r\n", __func__, sgl->length, data->blksz);

                        return -EINVAL;

                }

        }

And the output log

omap_hsmmc_setup_dma_transfer Sgl Length 612 Data Block Size 512

[ 1482.295658] omap_hsmmc 47810000.mmc: MMC start dma failure

[ 1482.301200] brcmf_sdiod_sglist_rw: CMD53 sg block write failed -22

[ 1482.308635] brcmf_sdio_txfail: sdio error, abort command and terminate frame

[ 1486.497015] omap_hsmmc_setup_dma_transfer Sgl Length 588 Data Block Size 512

[ 1486.504382] omap_hsmmc 47810000.mmc: MMC start dma failure

[ 1486.509921] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[ 1486.517263] brcmf_sdio_rxglom: glom read of 1536 bytes failed: -5

[ 1486.523634] brcmf_sdio_rxfail: abort command, terminate frame, send NAK

[ 1486.534431] omap_hsmmc_setup_dma_transfer Sgl Length 588 Data Block Size 512

[ 1486.541634] omap_hsmmc 47810000.mmc: MMC start dma failure

[ 1486.547828] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[ 1486.554147] brcmf_sdio_rxglom: glom read of 1536 bytes failed: -5

[ 1486.560291] brcmf_sdio_rxfail: abort command, terminate frame, send NAK

[ 1486.573765] omap_hsmmc_setup_dma_transfer Sgl Length 588 Data Block Size 512

[ 1486.580965] omap_hsmmc 47810000.mmc: MMC start dma failure

[ 1486.587165] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[ 1486.593490] brcmf_sdio_rxglom: glom read of 1536 bytes failed: -5

[ 1486.599633] brcmf_sdio_rxfail: abort command, terminate frame, send NAK

[ 1486.607711] omap_hsmmc_setup_dma_transfer Sgl Length 588 Data Block Size 512

[ 1486.615008] omap_hsmmc 47810000.mmc: MMC start dma failure

[ 1486.620544] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[ 1486.627460] brcmf_sdio_rxglom: glom read of 1536 bytes failed: -5

[ 1486.633754] brcmf_sdio_rxfail: abort command, terminate frame

Do you have any clue why the SG entry not aligned with block size

0 Likes
1 Solution
Anonymous
Not applicable

Alignment problem is solved. I had hardcore the alignment value in wrong place, so that txglomalign is not set properly. Now I'm setting(hardcore) through brcmf_of_probe function and  it is working properly without any issue. Seems to be it is not taking it from device tree node(i.e without device tree configuration, the driver is getting loaded). I think from kernel 4.5, device tree node support is properly added.

Regards,

Manoj

View solution in original post

0 Likes
12 Replies
Anonymous
Not applicable

1) Could you trace through(by adding debug prints or any other means) and see where the scatter list being created?     Is  brcmf_sdiod_sglist_rw is  where it gets created? 2)The block size for the scatter list may be coming from what is discovered during probe. Try and trace through to see where it is coming from.

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

vsb

Sorry for late reply. I was working in some other issue. Regarding wifi , we have hardcore the sgentry_align value in brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) function.

        /* platform specific configuration:

        *  alignments must be at least 4 bytes for ADMA

        */

        bus->head_align = ALIGNMENT;

        bus->sgentry_align = 512;

After the above fix, TX path sgentry list are aligned into 512 bytes, so we are not getting any dma error during tx packet send. But still alignment issue is there in RX path. Sg entry alignment for Rx packet is not happening properly(May be we are missing something) .

[  451.042783] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[  451.049691] brcmf_sdio_rxglom: glom read of 512 bytes failed: -5

[  451.055907] brcmf_sdio_rxfail: abort command, terminate frame, send NAK

[  451.064349] omap_hsmmc_setup_dma_transfer : count=0  sgl->length = 72 blksz = 512

[  451.071977] omap_hsmmc_setup_dma_transfer : count=1  sgl->length = 440 blksz = 512

[  451.080277] omap_hsmmc 47810000.mmc: MMC start dma failure

[  451.085920] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[  451.092357] brcmf_sdio_rxglom: glom read of 512 bytes failed: -5

[  451.099164] brcmf_sdio_rxfail: abort command, terminate frame, send NAK

[  451.114265] omap_hsmmc_setup_dma_transfer : count=0  sgl->length = 72 blksz = 512

[  451.121891] omap_hsmmc_setup_dma_transfer : count=1  sgl->length = 440 blksz = 512

[  451.130183] omap_hsmmc 47810000.mmc: MMC start dma failure

[  451.135824] brcmf_sdiod_sglist_rw: CMD53 sg block read failed -22

[  451.142050] brcmf_sdio_rxglom: glom read of 512 bytes failed: -5

[  451.148836] brcmf_sdio_rxfail: abort command, terminate frame, send NAK

[  451.164533] omap_hsmmc_setup_dma_transfer : count=0  sgl->length = 72 blksz = 512

[  451.172162] omap_hsmmc_setup_dma_transfer : count=1  sgl->length = 440 blksz = 512

[  451.180516] omap_hsmmc 47810000.mmc: MMC start dma failure

So, for the timing, we disable the sg list dma transfer(by enabling direct mem copy) for RX packet as below and also we have a made fix for kernel low memory issue(attached log) due to continuous buffer allocation.

******************

In bcmsdh.c

****************

int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,

                          struct sk_buff_head *pktq, uint totlen)

{

        struct sk_buff *glom_skb;

        struct sk_buff *skb;

        u32 addr = sdiodev->sbwad;

        int err = 0;

        brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",

                  addr, pktq->qlen);

        err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);

        if (err)

                goto done;

        if (pktq->qlen == 1)

                err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,

                                        pktq->next);

/*      else if (!sdiodev->sg_support) { */ /* Enable mem copy and Disable SG list DMA transfer*/

        else if (sdiodev->sg_support) {

                glom_skb = brcmu_pkt_buf_get_skb(totlen);

                if (!glom_skb)

                        return -ENOMEM;

                err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,

                                        glom_skb);

                if (err)

                        goto done;

                skb_queue_walk(pktq, skb) {

                        memcpy(skb->data, glom_skb->data, skb->len);

                        skb_pull(glom_skb, skb->len);

                }

                /* Fix for kernel low memory issue*/

                brcmu_pkt_buf_free_skb(glom_skb);

        } else

                err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr,

                                            pktq);

done:

        return err;

}

*************

sdio.c

*************

/* commented error message

                        if (sublen % bus->sgentry_align) {

                                brcmf_err("sublen %d not multiple of %d\n",

                                          sublen, bus->sgentry_align);

                        }

*/

Finally after the above fix, wifi is able to send and receive packets without any issue. Now, how we can solve the RX sg list alignment issue. Whether we are missing anything in the platform related data. And also can you explain below platform data, whether these data are related to RX sg list alignment issue.

* sd_head_align

* broken_sg_support

0 Likes
Anonymous
Not applicable

lovelymanoj

The alignment information is supposed to come from the SDIO host.  You may want to dig through to see why the SDIO host is not reporting the current alignment information.

Anonymous
Not applicable

Can you explain the below platform data.

* sd_head_align

* broken_sg_support

0 Likes
Anonymous
Not applicable

From include/linux/platform_data/brcmfmac-sdio.h

* broken_sg_support: flag for broken sg list support of SDIO host controller.

* Set this to true if the SDIO host controller has higher align requirement

* than 32 bytes for each scatterlist item.

*

* sd_head_align: alignment requirement for start of data buffer

0 Likes
Anonymous
Not applicable

The header file information is not detailed enough to understand the parameter. Can you provide any detailed write on this platform data

0 Likes
Anonymous
Not applicable

Alignment problem is solved. I had hardcore the alignment value in wrong place, so that txglomalign is not set properly. Now I'm setting(hardcore) through brcmf_of_probe function and  it is working properly without any issue. Seems to be it is not taking it from device tree node(i.e without device tree configuration, the driver is getting loaded). I think from kernel 4.5, device tree node support is properly added.

Regards,

Manoj

0 Likes
Anonymous
Not applicable

lovelymanoj

For the benefit of others, could you please post a patch with the changes that helped you.

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

vsb

I just hard cored the values in the probe function. Attached the patch file for that.

Anonymous
Not applicable

Thanks Manoj. I am putting the patch inline here. I am also glad you have it working.

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.c b/drivers/net/wireless/brcm80211/brcmfmac/of.c

index c824570..0e966d4 100644

--- a/drivers/net/wireless/brcm80211/brcmfmac/of.c

+++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c

@@ -32,9 +32,6 @@ void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)

  u32 irqf;

  u32 val;

- if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))

- return;

-

  sdiodev->pdata = devm_kzalloc(dev, sizeof(*sdiodev->pdata), GFP_KERNEL);

  if (!sdiodev->pdata)

  return;

@@ -42,15 +39,24 @@ void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)

  irq = irq_of_parse_and_map(np, 0);

  if (!irq) {

  brcmf_err("interrupt could not be mapped\n");

- devm_kfree(dev, sdiodev->pdata);

- return;

- }

- irqf = irqd_get_trigger_type(irq_get_irq_data(irq));

- sdiodev->pdata->oob_irq_supported = true;

- sdiodev->pdata->oob_irq_nr = irq;

- sdiodev->pdata->oob_irq_flags = irqf;

+ sdiodev->pdata->oob_irq_supported = false;

+ }

+ else {

+ sdiodev->pdata->oob_irq_supported = true;

+ irqf = irqd_get_trigger_type(irq_get_irq_data(irq));

+ sdiodev->pdata->oob_irq_nr = irq;

+ sdiodev->pdata->oob_irq_flags = irqf;

+ }

  if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)

  sdiodev->pdata->drive_strength = val;

+

+ if (of_property_read_u32(np, "brcm,sd_sgentry_align", &val) == 0)

+ {

+                sdiodev->pdata->sd_sgentry_align = val;

+ printk("%s: sd_sgentry_align= %d \r\n", __func__, val);

+ }

+ sdiodev->pdata->sd_sgentry_align = 512;

+ return;

}

Anonymous
Not applicable

I am using the TI AM335x (beagle bone black Rev c) board with Murata wifi module Type 1DX EVB ES2.0.

And using linux kernel 4.4.32 from TI SDK 03.02.00.05.

I made the following DTS changes. And applied the patch mentioned above. But I got rxfail resolved, but txfail is still present. Please let me know if anything to be done.

&mmc1 {

...

brcmf: brcmf@1 {

compatible = "brcm,bcm4329-fmac";

reg = <1>;

status = "okay";

    };

};

LOgs:

[ 35.951730] omap_hsmmc 48060000.mmc: MMC start dma failure

[ 35.971685] brcmf_sdiod_sglist_rw: CMD53 sg block write failed -22

[ 35.982574] brcmf_sdio_txfail: sdio error, abort command and terminate frame

0 Likes
Anonymous
Not applicable

When we are using Murata wifi module in our developer build which use tftp and nfs boot and not using eMMC in Beable bone black, WIfi is working fine.

But when we use the emmc for booting and Wifi module as SDIO from SD card slot, some time it works fine but some time we are observing following errors while wifi data transfer (ping)and when error occurs data transfer will not work.

Please let us know if anything to be done. 

Is this due to work around to use direct DMA instead of Sg List DMA transfer? How can we solve this ?

Following are the logs collected at different time:

When this errors not allowing to use the tty services

[ 12.236610] mmcblk0: error -110 sending status command, retrying

[ 12.298452] mmcblk0: error -110 sending status command, retrying

[ 12.348893] mmcblk0: error -110 sending status command, aborting

[   12.759549] mmcblk0: error -110 sending status command, retrying

[ 12.778985] mmcblk0: error -110 sending status command, retrying

[ 12.811931] mmcblk0: error -110 sending status command, aborting

[ 12.900171] mmcblk0: error -110 sending status command, retrying

[ 12.913618] mmcblk0: error -110 sending status command, retrying

[   12.945976] mmcblk0: error -110 sending status command, aborting

[ 12.956535] EXT4-fs error (device mmcblk0p2): ext4_find_entry:1450: inode #57299: comm systemd-udevd: reading directory lblock 0

[ 13.031028] mmcblk0: error -110 sending status command, retrying

[ 13.045101] mmcblk0: error -110 sending status command, retrying

[ 13.060595] mmcblk0: error -110 sending status command, aborting

[   13.073610] EXT4-fs error (device mmcblk0p2): ext4_find_entry:1450: inode #81629: comm systemd-rfkill: reading directory lblock 0

[ 13.144869] mmcblk0: error -110 sending status command, retrying

This won’t block the tty service

[ 21.436954] omap_hsmmc 48060000.mmc: MMC start dma failure

[ 21.442672] brcmf_sdiod_sglist_rw: CMD53 sg block write failed -22

[ 21.448904] brcmf_sdio_txfail: sdio error, abort command and terminate frame

[  313.945272] omap_hsmmc 48060000.mmc: MMC start dma failure

[  313.950858] brcmf_sdiod_sglist_rw: CMD53 sg block write failed -22

[  313.964960] brcmf_sdio_txfail: sdio error, abort command and terminate frame

r[  315.118948] omap_hsmmc 48060000.mmc: MMC start dma failure

[  315.125458] brcmf_sdiod_sglist_rw: CMD53 sg block write failed -22

[  315.131684] brcmf_sdio_txfail: sdio error, abort command and terminate frame

Some time we observe the following Error

root@am335x-evm:~# dmesg | grep brcmf

[ 6.221257] brcmf_of_probe: interrupt could not be mapped

[ 6.294082] brcmfmac: F1 signature read @0x18000000=0x1531a9a6

[ 6.312739] brcmf_sdio_drivestrengthinit: No SDIO Drive strength init done for chip 43430 rev 1 pmurev 24

[ 7.002733] brcmf_c_preinit_dcmds: Firmware version = wl0: Apr 19 2017 03:56:55 version 7.45.98.16 (r664736) FWID 01-fd43956f

[ 8.372827] brcmf_cfg80211_reg_notifier: not a ISO3166 code

[ 18.972729] brcmf_sdiod_regrw_helper: failed to read data F1@0x0a020, err: -110

[ 18.980141] brcmf_sdio_isr: failed backplane access