12 Replies Latest reply on Aug 11, 2017 2:50 AM by vinaykumar.shettar_2291891

    brcmfamc - OMAP SG entry not aligned with block size

    vens

      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

        • 1. Re: brcmfamc - OMAP SG entry not aligned with block size
          vens

          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.

          • 2. Re: brcmfamc - OMAP SG entry not aligned with block size
            manoj_1578136

            vens

            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

            • 3. Re: brcmfamc - OMAP SG entry not aligned with block size
              vens

              manoj_1578136

               

              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.

              1 of 1 people found this helpful
              • 4. Re: brcmfamc - OMAP SG entry not aligned with block size
                manoj_1578136

                Can you explain the below platform data.

                 

                * sd_head_align

                * broken_sg_support

                 

                 

                 

                • 5. Re: brcmfamc - OMAP SG entry not aligned with block size
                  vens

                  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

                  • 6. Re: brcmfamc - OMAP SG entry not aligned with block size
                    manoj_1578136

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

                    • 7. Re: brcmfamc - OMAP SG entry not aligned with block size
                      manoj_1578136

                      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

                      • 8. Re: brcmfamc - OMAP SG entry not aligned with block size
                        vens

                        manoj_1578136

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

                        • 9. Re: brcmfamc - OMAP SG entry not aligned with block size
                          manoj_1578136

                          vens

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

                          1 of 1 people found this helpful
                          • 10. Re: brcmfamc - OMAP SG entry not aligned with block size
                            vens

                            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;

                            }

                            3 of 3 people found this helpful
                            • 11. Re: brcmfamc - OMAP SG entry not aligned with block size
                              vinaykumar.shettar_2291891

                              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

                              • 12. Re: brcmfamc - OMAP SG entry not aligned with block size
                                vinaykumar.shettar_2291891

                                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