You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2021/07/28 16:47:12 UTC

[incubator-nuttx] branch master updated: bcm43xxx: fixed issues with unaligned buffers for DMA transfers. This fixes the following errors: - "stm32_dmacapable: stm32_dmacapable: burst crosses 1KiB up_assert: Assertion failed at file:chip/stm32_sdio.c line: 2890 task: init"

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new ff2dd12  bcm43xxx: fixed issues with unaligned buffers for DMA transfers. This fixes the following errors: - "stm32_dmacapable: stm32_dmacapable: burst crosses 1KiB up_assert: Assertion failed at file:chip/stm32_sdio.c line: 2890 task: init"
ff2dd12 is described below

commit ff2dd12c3c3f5c561fedfa54537d51177ccd1158
Author: Alexander Lunev <al...@mail.ru>
AuthorDate: Tue Jul 27 03:43:12 2021 +0300

    bcm43xxx: fixed issues with unaligned buffers for DMA transfers.
    This fixes the following errors:
    - "stm32_dmacapable: stm32_dmacapable: burst crosses 1KiB
    up_assert: Assertion failed at file:chip/stm32_sdio.c line: 2890 task: init"
    
    - "stm32_dmacapable: stm32_dmacapable: burst crosses 1KiB
    up_assert: Assertion failed at file:chip/stm32_sdio.c line: 2808 task: bcmf"
    
    bcm43xxx: replaced all occurrences of "__attribute__((packed))" by
    compiler independent "begin_packed_struct / end_packed_struct".
---
 boards/arm/stm32/emw3162/configs/wlan/defconfig   |  1 +
 boards/arm/stm32/emw3162/scripts/ld.script        |  3 +-
 boards/arm/stm32/photon/configs/wlan/defconfig    |  1 +
 boards/arm/stm32/photon/scripts/photon_dfu.ld     |  3 +-
 boards/arm/stm32/photon/src/stm32_wlan_firmware.c | 20 ++++++++++--
 drivers/wireless/ieee80211/bcm43xxx/Kconfig       |  8 +++++
 drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c    | 12 +++----
 drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.h    |  4 +--
 drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c    |  4 +--
 drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h   | 16 +++++++++
 drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c  | 40 ++++++++++++++++++-----
 11 files changed, 87 insertions(+), 25 deletions(-)

diff --git a/boards/arm/stm32/emw3162/configs/wlan/defconfig b/boards/arm/stm32/emw3162/configs/wlan/defconfig
index fe1189a..16f9acf 100644
--- a/boards/arm/stm32/emw3162/configs/wlan/defconfig
+++ b/boards/arm/stm32/emw3162/configs/wlan/defconfig
@@ -27,6 +27,7 @@ CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
 CONFIG_HAVE_CXXINITIALIZE=y
 CONFIG_IEEE80211_BROADCOM_BCM43362=y
+CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT=16
 CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO=y
 CONFIG_INTELHEX_BINARY=y
 CONFIG_LIBM=y
diff --git a/boards/arm/stm32/emw3162/scripts/ld.script b/boards/arm/stm32/emw3162/scripts/ld.script
index eb3611a..493d32f 100644
--- a/boards/arm/stm32/emw3162/scripts/ld.script
+++ b/boards/arm/stm32/emw3162/scripts/ld.script
@@ -45,11 +45,10 @@ SECTIONS
         *(.fixup)
         *(.gnu.warning)
 
-        . = ALIGN(0x4);
         wlan_firmware_image_location = .;
         *(.wlan_firmware_image .wlan_firmware_image.*)
         wlan_firmware_image_end = .;
-        . = ALIGN(0x4);
+
         wlan_nvram_image_location = .;
         *(.wlan_nvram_image .wlan_nvram_image.*)
         wlan_nvram_image_end = .;
diff --git a/boards/arm/stm32/photon/configs/wlan/defconfig b/boards/arm/stm32/photon/configs/wlan/defconfig
index 3a346d4..e061438 100644
--- a/boards/arm/stm32/photon/configs/wlan/defconfig
+++ b/boards/arm/stm32/photon/configs/wlan/defconfig
@@ -32,6 +32,7 @@ CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
 CONFIG_HAVE_CXXINITIALIZE=y
 CONFIG_IEEE80211_BROADCOM_BCM43362=y
+CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT=16
 CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO=y
 CONFIG_INTELHEX_BINARY=y
 CONFIG_LIBM=y
diff --git a/boards/arm/stm32/photon/scripts/photon_dfu.ld b/boards/arm/stm32/photon/scripts/photon_dfu.ld
index 3ce8a66..7e55c02 100644
--- a/boards/arm/stm32/photon/scripts/photon_dfu.ld
+++ b/boards/arm/stm32/photon/scripts/photon_dfu.ld
@@ -48,11 +48,10 @@ SECTIONS
         *(.fixup)
         *(.gnu.warning)
 
-        . = ALIGN(0x4);
         wlan_firmware_image_location = .;
         *(.wlan_firmware_image .wlan_firmware_image.*)
         wlan_firmware_image_end = .;
-        . = ALIGN(0x4);
+
         wlan_nvram_image_location = .;
         *(.wlan_nvram_image .wlan_nvram_image.*)
         wlan_nvram_image_end = .;
diff --git a/boards/arm/stm32/photon/src/stm32_wlan_firmware.c b/boards/arm/stm32/photon/src/stm32_wlan_firmware.c
index 310a99a..7f7866a 100644
--- a/boards/arm/stm32/photon/src/stm32_wlan_firmware.c
+++ b/boards/arm/stm32/photon/src/stm32_wlan_firmware.c
@@ -51,8 +51,16 @@
 
 /* Character array of NVRAM image */
 
+/* SDIO_RXDMA32_CONFIG and SDIO_TXDMA32_CONFIG values in stm32_sdio.c
+ * give the DMA burst length of 16 bytes
+ * (DMA_SCR_MSIZE_32BITS x DMA_SCR_MBURST_INCR4).
+ * Thus the following alignment should be 0x10.
+ */
+
 const char
-__attribute__((section(".wlan_nvram_image"))) bcm43362_nvram_image[] =
+locate_data(".wlan_nvram_image")
+aligned_data(CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT)
+bcm43362_nvram_image[] =
         "manfid=0x2d0"                                              "\x00"
         "prodid=0x492"                                              "\x00"
         "vendid=0x14e4"                                             "\x00"
@@ -115,8 +123,16 @@ __attribute__((section(".wlan_nvram_image"))) bcm43362_nvram_image[] =
 
 const unsigned int bcm43362_nvram_image_len = sizeof(bcm43362_nvram_image);
 
+/* SDIO_RXDMA32_CONFIG and SDIO_TXDMA32_CONFIG values in stm32_sdio.c
+ * give the DMA burst length of 16 bytes
+ * (DMA_SCR_MSIZE_32BITS x DMA_SCR_MBURST_INCR4).
+ * Thus the following alignment should be 0x10.
+ */
+
 const uint8_t
-__attribute__((section(".wlan_firmware_image"))) bcm43362_firmware_image[] =
+locate_data(".wlan_firmware_image")
+aligned_data(CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT)
+bcm43362_firmware_image[] =
 {
   0x00, 0x00, 0x00, 0x00, 0xcd, 0xc2, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00,
   0x91, 0xc1, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00,
diff --git a/drivers/wireless/ieee80211/bcm43xxx/Kconfig b/drivers/wireless/ieee80211/bcm43xxx/Kconfig
index e466116..5361e17 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/Kconfig
+++ b/drivers/wireless/ieee80211/bcm43xxx/Kconfig
@@ -101,4 +101,12 @@ config IEEE80211_BROADCOM_NINTERFACES
 	default 1
 	depends on EXPERIMENTAL
 
+config IEEE80211_BROADCOM_DMABUF_ALIGNMENT
+	int "DMA buffer address alignment boundary"
+	default 4
+	range 4 64
+	---help---
+		This parameter should be set depending on
+		the used SOC DMA configuration.
+
 endif # IEEE80211_BROADCOM_FULLMAC
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c
index c32305f..458d8a1 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c
@@ -48,30 +48,30 @@
  * Private Types
  ****************************************************************************/
 
-struct __attribute__((packed)) bcmf_bdc_header
+begin_packed_struct struct bcmf_bdc_header
 {
   uint8_t flags;       /* bdc frame flags */
   uint8_t priority;    /* bdc frame priority */
   uint8_t flags2;      /* bdc frame additional flags */
   uint8_t data_offset; /* Offset from end of header to payload data, in 4-bytes count */
-};
+} end_packed_struct;
 
-struct __attribute__((packed)) bcmf_eth_header
+begin_packed_struct struct bcmf_eth_header
 {
   uint16_t type;     /* Vendor specific type */
   uint16_t len;      /* Event data length */
   uint8_t  version;  /* Protocol version */
   uint8_t  oui[3];   /* Organizationally unique identifier */
   uint16_t usr_type; /* User specific type */
-};
+} end_packed_struct;
 
-struct __attribute__((packed)) bcmf_event_msg
+begin_packed_struct struct bcmf_event_msg
 {
   struct ether_header    eth;
   struct bcmf_eth_header bcm_eth;
   struct bcmf_event_s    event;
   uint8_t                data[0];
-};
+} end_packed_struct;
 
 /****************************************************************************
  * Private Data
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.h
index 52b644c..68ebb08 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.h
@@ -33,7 +33,7 @@
 
 /* Event frame content */
 
-struct __attribute__((packed)) bcmf_event_s
+begin_packed_struct struct bcmf_event_s
 {
   uint16_t version;       /* Vendor specific type */
   uint16_t flags;
@@ -46,7 +46,7 @@ struct __attribute__((packed)) bcmf_event_s
   char     src_name[16];  /* Event source interface name */
   uint8_t  dst_id;        /* Event destination interface id */
   uint8_t  bss_cfg_id;
-};
+} end_packed_struct;
 
 /* Event callback handler */
 
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c
index b260f4a..3274883 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c
@@ -54,13 +54,13 @@
  * Private Types
  ****************************************************************************/
 
-struct __attribute__((packed)) bcmf_cdc_header
+begin_packed_struct struct bcmf_cdc_header
 {
   uint32_t cmd;    /* Command to be sent */
   uint32_t len;    /* Size of command data */
   uint32_t flags;  /* cdc request flags, see above */
   uint32_t status; /* Returned status code from chip */
-};
+} end_packed_struct;
 
 /****************************************************************************
  * Private Function Prototypes
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h
index 7059314..7852e5c 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h
@@ -42,6 +42,7 @@
  ****************************************************************************/
 
 #define HEADER_SIZE        0x12 /* Default sdpcm + bdc header size */
+#define FIRST_WORD_SIZE    4
 
 /* TODO move to Kconfig */
 
@@ -115,6 +116,21 @@ struct bcmf_sdio_frame
   struct bcmf_frame_s header;
   bool                tx;
   dq_entry_t          list_entry;
+  uint8_t             pad[CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT -
+                          FIRST_WORD_SIZE]
+  aligned_data(CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT);
+
+  /* pad[] array is used and aligned in order to make the following data[]
+   * buffer aligned beginning from the offset of 4 bytes to the address
+   * boundary for SDIO DMA transfers.
+   * The first 4 bytes of data[] buffer are not directly used in DMA
+   * transfers. Instead, they are used as the initial phase just to get
+   * the length of the remaining long data to be read. Thus only
+   * the remaining part of data[] buffer beginning from the offset of 4 bytes
+   * is required to be aligned to the address boundary set by
+   * CONFIG_IEEE80211_BROADCOM_SDIO_DMA_BUF_ALIGNMENT parameter.
+   */
+
   uint8_t             data[HEADER_SIZE + MAX_NETDEV_PKTSIZE +
                            CONFIG_NET_GUARDSIZE];
 };
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c
index 01266d6..ce3cba3 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c
@@ -58,7 +58,7 @@
  * Private Types
  ****************************************************************************/
 
-struct __attribute__((packed)) bcmf_sdpcm_header
+begin_packed_struct struct bcmf_sdpcm_header
 {
   uint16_t size;
   uint16_t checksum;
@@ -69,7 +69,7 @@ struct __attribute__((packed)) bcmf_sdpcm_header
   uint8_t  flow_control;
   uint8_t  credit;
   uint16_t padding;
-};
+} end_packed_struct;
 
 /****************************************************************************
  * Private Function Prototypes
@@ -153,9 +153,13 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
 
   header = (struct bcmf_sdpcm_header *)sframe->data;
 
-  /* Read header */
+  /* Read the first 4 bytes of sdpcm header
+   * to get the length of the following data to be read
+   */
 
-  ret = bcmf_transfer_bytes(sbus, false, 2, 0, (uint8_t *)header, 4);
+  ret = bcmf_transfer_bytes(sbus, false, 2, 0,
+                            (uint8_t *)header,
+                            FIRST_WORD_SIZE);
   if (ret != OK)
     {
       wlinfo("failread size\n");
@@ -188,10 +192,11 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
       goto exit_abort;
     }
 
-  /* Read remaining frame data */
+  /* Read the remaining frame data (the buffer is DMA aligned here) */
 
   ret = bcmf_transfer_bytes(sbus, false, 2, 0,
-                           (uint8_t *)header + 4, len - 4);
+                           (uint8_t *)header + FIRST_WORD_SIZE,
+                           len - FIRST_WORD_SIZE);
   if (ret != OK)
     {
       ret = -EIO;
@@ -319,8 +324,25 @@ int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv)
                (unsigned long)sframe->header.base);
 #endif
 
-  ret = bcmf_transfer_bytes(sbus, true, 2, 0, sframe->header.base,
-                            sframe->header.len);
+  /* Write the first 4 bytes of sdpcm header */
+
+  ret = bcmf_transfer_bytes(sbus, true, 2, 0,
+                            sframe->header.base,
+                            FIRST_WORD_SIZE);
+  if (ret != OK)
+    {
+      /* TODO handle retry count and remove frame from queue + abort TX */
+
+      wlinfo("fail send frame %d\n", ret);
+      ret = -EIO;
+      goto exit_abort;
+    }
+
+  /* Write the remaining frame data (the buffer is DMA aligned here) */
+
+  ret = bcmf_transfer_bytes(sbus, true, 2, 0,
+                            sframe->header.base + FIRST_WORD_SIZE,
+                            sframe->header.len - FIRST_WORD_SIZE);
   if (ret != OK)
     {
       /* TODO handle retry count and remove frame from queue + abort TX */
@@ -364,7 +386,7 @@ int bcmf_sdpcm_queue_frame(FAR struct bcmf_dev_s *priv,
   FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
   struct bcmf_sdio_frame *sframe = (struct bcmf_sdio_frame *)frame;
   struct bcmf_sdpcm_header *header =
-                           (struct bcmf_sdpcm_header *)sframe->data;
+    (struct bcmf_sdpcm_header *)sframe->data;
 
   /* Prepare sw header */