mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
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".
This commit is contained in:
committed by
Alan Carvalho de Assis
parent
2866c27c19
commit
ff2dd12c3c
@@ -27,6 +27,7 @@ CONFIG_FS_PROCFS=y
|
|||||||
CONFIG_HAVE_CXX=y
|
CONFIG_HAVE_CXX=y
|
||||||
CONFIG_HAVE_CXXINITIALIZE=y
|
CONFIG_HAVE_CXXINITIALIZE=y
|
||||||
CONFIG_IEEE80211_BROADCOM_BCM43362=y
|
CONFIG_IEEE80211_BROADCOM_BCM43362=y
|
||||||
|
CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT=16
|
||||||
CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO=y
|
CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO=y
|
||||||
CONFIG_INTELHEX_BINARY=y
|
CONFIG_INTELHEX_BINARY=y
|
||||||
CONFIG_LIBM=y
|
CONFIG_LIBM=y
|
||||||
|
|||||||
@@ -45,11 +45,10 @@ SECTIONS
|
|||||||
*(.fixup)
|
*(.fixup)
|
||||||
*(.gnu.warning)
|
*(.gnu.warning)
|
||||||
|
|
||||||
. = ALIGN(0x4);
|
|
||||||
wlan_firmware_image_location = .;
|
wlan_firmware_image_location = .;
|
||||||
*(.wlan_firmware_image .wlan_firmware_image.*)
|
*(.wlan_firmware_image .wlan_firmware_image.*)
|
||||||
wlan_firmware_image_end = .;
|
wlan_firmware_image_end = .;
|
||||||
. = ALIGN(0x4);
|
|
||||||
wlan_nvram_image_location = .;
|
wlan_nvram_image_location = .;
|
||||||
*(.wlan_nvram_image .wlan_nvram_image.*)
|
*(.wlan_nvram_image .wlan_nvram_image.*)
|
||||||
wlan_nvram_image_end = .;
|
wlan_nvram_image_end = .;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ CONFIG_FS_PROCFS=y
|
|||||||
CONFIG_HAVE_CXX=y
|
CONFIG_HAVE_CXX=y
|
||||||
CONFIG_HAVE_CXXINITIALIZE=y
|
CONFIG_HAVE_CXXINITIALIZE=y
|
||||||
CONFIG_IEEE80211_BROADCOM_BCM43362=y
|
CONFIG_IEEE80211_BROADCOM_BCM43362=y
|
||||||
|
CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT=16
|
||||||
CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO=y
|
CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO=y
|
||||||
CONFIG_INTELHEX_BINARY=y
|
CONFIG_INTELHEX_BINARY=y
|
||||||
CONFIG_LIBM=y
|
CONFIG_LIBM=y
|
||||||
|
|||||||
@@ -48,11 +48,10 @@ SECTIONS
|
|||||||
*(.fixup)
|
*(.fixup)
|
||||||
*(.gnu.warning)
|
*(.gnu.warning)
|
||||||
|
|
||||||
. = ALIGN(0x4);
|
|
||||||
wlan_firmware_image_location = .;
|
wlan_firmware_image_location = .;
|
||||||
*(.wlan_firmware_image .wlan_firmware_image.*)
|
*(.wlan_firmware_image .wlan_firmware_image.*)
|
||||||
wlan_firmware_image_end = .;
|
wlan_firmware_image_end = .;
|
||||||
. = ALIGN(0x4);
|
|
||||||
wlan_nvram_image_location = .;
|
wlan_nvram_image_location = .;
|
||||||
*(.wlan_nvram_image .wlan_nvram_image.*)
|
*(.wlan_nvram_image .wlan_nvram_image.*)
|
||||||
wlan_nvram_image_end = .;
|
wlan_nvram_image_end = .;
|
||||||
|
|||||||
@@ -51,8 +51,16 @@
|
|||||||
|
|
||||||
/* Character array of NVRAM image */
|
/* 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
|
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"
|
"manfid=0x2d0" "\x00"
|
||||||
"prodid=0x492" "\x00"
|
"prodid=0x492" "\x00"
|
||||||
"vendid=0x14e4" "\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);
|
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
|
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,
|
0x00, 0x00, 0x00, 0x00, 0xcd, 0xc2, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00,
|
||||||
0x91, 0xc1, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00,
|
0x91, 0xc1, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00, 0x91, 0xc1, 0x00, 0x00,
|
||||||
|
|||||||
@@ -101,4 +101,12 @@ config IEEE80211_BROADCOM_NINTERFACES
|
|||||||
default 1
|
default 1
|
||||||
depends on EXPERIMENTAL
|
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
|
endif # IEEE80211_BROADCOM_FULLMAC
|
||||||
|
|||||||
@@ -48,30 +48,30 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct __attribute__((packed)) bcmf_bdc_header
|
begin_packed_struct struct bcmf_bdc_header
|
||||||
{
|
{
|
||||||
uint8_t flags; /* bdc frame flags */
|
uint8_t flags; /* bdc frame flags */
|
||||||
uint8_t priority; /* bdc frame priority */
|
uint8_t priority; /* bdc frame priority */
|
||||||
uint8_t flags2; /* bdc frame additional flags */
|
uint8_t flags2; /* bdc frame additional flags */
|
||||||
uint8_t data_offset; /* Offset from end of header to payload data, in 4-bytes count */
|
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 type; /* Vendor specific type */
|
||||||
uint16_t len; /* Event data length */
|
uint16_t len; /* Event data length */
|
||||||
uint8_t version; /* Protocol version */
|
uint8_t version; /* Protocol version */
|
||||||
uint8_t oui[3]; /* Organizationally unique identifier */
|
uint8_t oui[3]; /* Organizationally unique identifier */
|
||||||
uint16_t usr_type; /* User specific type */
|
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 ether_header eth;
|
||||||
struct bcmf_eth_header bcm_eth;
|
struct bcmf_eth_header bcm_eth;
|
||||||
struct bcmf_event_s event;
|
struct bcmf_event_s event;
|
||||||
uint8_t data[0];
|
uint8_t data[0];
|
||||||
};
|
} end_packed_struct;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
/* Event frame content */
|
/* Event frame content */
|
||||||
|
|
||||||
struct __attribute__((packed)) bcmf_event_s
|
begin_packed_struct struct bcmf_event_s
|
||||||
{
|
{
|
||||||
uint16_t version; /* Vendor specific type */
|
uint16_t version; /* Vendor specific type */
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
@@ -46,7 +46,7 @@ struct __attribute__((packed)) bcmf_event_s
|
|||||||
char src_name[16]; /* Event source interface name */
|
char src_name[16]; /* Event source interface name */
|
||||||
uint8_t dst_id; /* Event destination interface id */
|
uint8_t dst_id; /* Event destination interface id */
|
||||||
uint8_t bss_cfg_id;
|
uint8_t bss_cfg_id;
|
||||||
};
|
} end_packed_struct;
|
||||||
|
|
||||||
/* Event callback handler */
|
/* Event callback handler */
|
||||||
|
|
||||||
|
|||||||
@@ -54,13 +54,13 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct __attribute__((packed)) bcmf_cdc_header
|
begin_packed_struct struct bcmf_cdc_header
|
||||||
{
|
{
|
||||||
uint32_t cmd; /* Command to be sent */
|
uint32_t cmd; /* Command to be sent */
|
||||||
uint32_t len; /* Size of command data */
|
uint32_t len; /* Size of command data */
|
||||||
uint32_t flags; /* cdc request flags, see above */
|
uint32_t flags; /* cdc request flags, see above */
|
||||||
uint32_t status; /* Returned status code from chip */
|
uint32_t status; /* Returned status code from chip */
|
||||||
};
|
} end_packed_struct;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define HEADER_SIZE 0x12 /* Default sdpcm + bdc header size */
|
#define HEADER_SIZE 0x12 /* Default sdpcm + bdc header size */
|
||||||
|
#define FIRST_WORD_SIZE 4
|
||||||
|
|
||||||
/* TODO move to Kconfig */
|
/* TODO move to Kconfig */
|
||||||
|
|
||||||
@@ -115,6 +116,21 @@ struct bcmf_sdio_frame
|
|||||||
struct bcmf_frame_s header;
|
struct bcmf_frame_s header;
|
||||||
bool tx;
|
bool tx;
|
||||||
dq_entry_t list_entry;
|
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 +
|
uint8_t data[HEADER_SIZE + MAX_NETDEV_PKTSIZE +
|
||||||
CONFIG_NET_GUARDSIZE];
|
CONFIG_NET_GUARDSIZE];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct __attribute__((packed)) bcmf_sdpcm_header
|
begin_packed_struct struct bcmf_sdpcm_header
|
||||||
{
|
{
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
@@ -69,7 +69,7 @@ struct __attribute__((packed)) bcmf_sdpcm_header
|
|||||||
uint8_t flow_control;
|
uint8_t flow_control;
|
||||||
uint8_t credit;
|
uint8_t credit;
|
||||||
uint16_t padding;
|
uint16_t padding;
|
||||||
};
|
} end_packed_struct;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
@@ -153,9 +153,13 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
|
|||||||
|
|
||||||
header = (struct bcmf_sdpcm_header *)sframe->data;
|
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)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
wlinfo("failread size\n");
|
wlinfo("failread size\n");
|
||||||
@@ -188,10 +192,11 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
|
|||||||
goto exit_abort;
|
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,
|
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)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
@@ -319,8 +324,25 @@ int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv)
|
|||||||
(unsigned long)sframe->header.base);
|
(unsigned long)sframe->header.base);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = bcmf_transfer_bytes(sbus, true, 2, 0, sframe->header.base,
|
/* Write the first 4 bytes of sdpcm header */
|
||||||
sframe->header.len);
|
|
||||||
|
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)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
/* TODO handle retry count and remove frame from queue + abort TX */
|
/* TODO handle retry count and remove frame from queue + abort TX */
|
||||||
|
|||||||
Reference in New Issue
Block a user