Skip to content

Commit f8368d2

Browse files
committed
drivers: wifi: brcmfmac: address review (chip-ID constants, CLM Kconfig)
Address @tchebb's second review pass: * Named constants for chip IDs (BRCM_CC_43430_CHIP_ID, _43439_, _4345_) matching Linux brcm_hw_ids.h; replace bare 43430 / 43439 / 0xa9a6 / 0x4345 throughout. This also fixes the brcmfmac_init() CLM gate and brcmfmac_chip_cm3_set_passive() bank-3 gate, both of which were checking the same chip ID twice (43430 == 0xa9a6) and so never fired on CYW43439. * Drop the chip-ID gate on the CLM blob upload. Linux brcmfmac doesn't gate this -- it just uploads if a blob is provided, silently skips if not. Mirror that: skip when brcmfmac_clm_blob_len is zero. Removes the hallucinated "firmware refuses the iovar" rationale. * Wire the CLM blob into the build system the same way as firmware and NVRAM: new WIFI_BRCMFMAC_CLM_FILE Kconfig string (default empty), CMake generates brcmfmac_clm_blob.inc from the named blob, brcmfmac_fw_blob.c #include's it. Empty string -> empty .inc -> zero-length array -> upload skipped. Also fixes a latent link error: brcmfmac_clm_blob[] was declared extern but never defined. * Named constants for the WL_REG_ON pulse delays (was bare 10/250), matching WHD's 20/150 values for this chip family. * Named constants for the dload header flags (BRCMF_DL_BEGIN, _DL_END, _DL_CRC_IN_HDR, _DL_TYPE_CLM) and the CLM upload chunk size, replacing magic 2/4/(1<<12)/512 ints in brcmfmac_process_clm_blob. * Bump the NVRAM scratch buffer to 4 KiB so it covers the largest NVRAM currently in linux-firmware (3099 bytes after the footer). Signed-off-by: Jonathan E. Peace <jep@alphabetiq.com>
1 parent 6137ee1 commit f8368d2

7 files changed

Lines changed: 93 additions & 27 deletions

File tree

drivers/wifi/brcmfmac/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ if(CONFIG_BUILD_ONLY_NO_BLOBS)
2323
# which is the expected failure mode for a no-blobs build.
2424
file(WRITE ${brcmfmac_gen_dir}/brcmfmac_fw.inc "")
2525
file(WRITE ${brcmfmac_gen_dir}/brcmfmac_nvram.inc "")
26+
file(WRITE ${brcmfmac_gen_dir}/brcmfmac_clm_blob.inc "")
2627
else()
2728
# Pull the firmware and per-board NVRAM from hal_broadcom (fetched
2829
# via `west blobs fetch hal_broadcom`) and convert each into a
@@ -37,6 +38,17 @@ else()
3738
generate_inc_file_for_target(${ZEPHYR_CURRENT_LIBRARY}
3839
${brcmfmac_blob_dir}/${CONFIG_WIFI_BRCMFMAC_NVRAM_FILE}
3940
${brcmfmac_gen_dir}/brcmfmac_nvram.inc)
41+
42+
# CLM blob is optional: a board that needs it sets
43+
# CONFIG_WIFI_BRCMFMAC_CLM_FILE in its defconfig; an unset/empty
44+
# string links a zero-length array and the driver skips upload.
45+
if(CONFIG_WIFI_BRCMFMAC_CLM_FILE STREQUAL "")
46+
file(WRITE ${brcmfmac_gen_dir}/brcmfmac_clm_blob.inc "")
47+
else()
48+
generate_inc_file_for_target(${ZEPHYR_CURRENT_LIBRARY}
49+
${brcmfmac_blob_dir}/${CONFIG_WIFI_BRCMFMAC_CLM_FILE}
50+
${brcmfmac_gen_dir}/brcmfmac_clm_blob.inc)
51+
endif()
4052
endif()
4153

4254
endif()

drivers/wifi/brcmfmac/Kconfig.brcmfmac

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ config WIFI_BRCMFMAC_NVRAM_FILE
4141
${ZEPHYR_HAL_BROADCOM_MODULE_DIR}/zephyr/blobs/img/brcmfmac/.
4242
Encodes board-specific antenna, calibration and PA settings.
4343

44+
config WIFI_BRCMFMAC_CLM_FILE
45+
string "CLM blob file name (under hal_broadcom blobs)"
46+
default ""
47+
help
48+
Optional Country Locale Matrix blob under
49+
${ZEPHYR_HAL_BROADCOM_MODULE_DIR}/zephyr/blobs/img/brcmfmac/.
50+
Required by chips whose firmware ships without built-in regulatory
51+
tables (e.g. BCM43458F); chips that have them (e.g. BCM43430A1)
52+
still accept the upload harmlessly. Leave empty to skip CLM upload
53+
entirely -- the driver links a zero-length blob in that case.
54+
4455
config WIFI_BRCMFMAC_RX_THREAD_STACK_SIZE
4556
int "RX thread stack size"
4657
default 4096

drivers/wifi/brcmfmac/brcmfmac_chip.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,11 @@ int brcmfmac_chip_read_id(struct brcmfmac_data *data)
350350
int brcmfmac_chip_ram_data(struct brcmfmac_data *data)
351351
{
352352
/* TODO: Read ram_size from core registers like in Linux. */
353-
if (data->chip_id == 43430 || data->chip_id == 43439) {
353+
if (data->chip_id == BRCM_CC_43430_CHIP_ID ||
354+
data->chip_id == BRCM_CC_43439_CHIP_ID) {
354355
data->ram_base = 0u;
355356
data->ram_size = 0x80000u;
356-
} else if (data->chip_id == 0x4345) {
357+
} else if (data->chip_id == BRCM_CC_4345_CHIP_ID) {
357358
data->ram_base = 0x198000u;
358359
data->ram_size = 0xC8000u;
359360
} else {
@@ -501,7 +502,8 @@ static int brcmfmac_chip_cm3_set_passive(struct brcmfmac_data *data)
501502
* present (BCM4329, BCM43236) or has a different PDA layout
502503
* (BCM43340, BCM4334) and the write would misconfigure RAM.
503504
*/
504-
if (data->chip_id == 43430 || data->chip_id == 0xa9a6) {
505+
if (data->chip_id == BRCM_CC_43430_CHIP_ID ||
506+
data->chip_id == BRCM_CC_43439_CHIP_ID) {
505507
(void)brcmfmac_sdio_backplane_write32(data,
506508
sr->base + SOCRAM_BANKIDX_OFFSET, 3);
507509
(void)brcmfmac_sdio_backplane_write32(data,

drivers/wifi/brcmfmac/brcmfmac_core.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,28 @@
2727

2828
LOG_MODULE_REGISTER(brcmfmac, CONFIG_WIFI_LOG_LEVEL);
2929

30+
/* WL_REG_ON pulse timing. The chip's CBUCK regulator needs a brief window
31+
* to fully discharge before re-power, then ~150 ms for the chip's clocks
32+
* to come up and the bootloader to reach a state where F0/F1 enumerate.
33+
* Matches the values WHD (Cypress's HAL) uses for the same family.
34+
*/
35+
#define BRCMFMAC_REG_ON_LOW_DELAY_MS 20
36+
#define BRCMFMAC_REG_ON_HIGH_DELAY_MS 150
37+
38+
/* CLM blob upload chunking. Linux uses 1400 bytes/chunk; we cap at 512
39+
* because brcmfmac_bcdc_iovar_set caps the payload at 1024 bytes total
40+
* and the dload header eats 12 of those.
41+
*/
42+
#define BRCMFMAC_CLM_CHUNK_SIZE 512
43+
3044
static int brcmfmac_initialization(struct brcmfmac_data *data)
3145
{
3246
int ret = brcmfmac_chip_read_id(data);
3347

3448
if (ret != 0) {
3549
return ret;
3650
}
37-
if (data->chip_id == 43430 && data->chip_rev == 1) {
51+
if (data->chip_id == BRCM_CC_43430_CHIP_ID && data->chip_rev == 1) {
3852
LOG_INF(" -> matches BCM43430A1");
3953
}
4054

@@ -98,15 +112,15 @@ static int brcmfmac_power_on(const struct device *dev)
98112
}
99113

100114
/* Allow CBUCK regulator to discharge */
101-
k_msleep(10);
115+
k_msleep(BRCMFMAC_REG_ON_LOW_DELAY_MS);
102116

103117
/* WIFI power on */
104118
ret = gpio_pin_set_dt(&cfg->reg_on, 1);
105119
if (ret) {
106120
return ret;
107121
}
108122

109-
k_msleep(250); /* TODO: Make constant */
123+
k_msleep(BRCMFMAC_REG_ON_HIGH_DELAY_MS);
110124
#else
111125
(void)dev;
112126
#endif /* DT_INST_NODE_HAS_PROP(0, reg_on_gpios) */
@@ -159,24 +173,23 @@ static int brcmfmac_probe_sdio(const struct device *dev)
159173

160174
static int brcmfmac_process_clm_blob(struct brcmfmac_data *data)
161175
{
162-
const size_t chunk_size = 512;
163176
struct brcmf_dload_data_le *hdr;
164-
uint8_t buf[sizeof(*hdr) + chunk_size];
177+
uint8_t buf[sizeof(*hdr) + BRCMFMAC_CLM_CHUNK_SIZE];
165178
const uint8_t *current = brcmfmac_clm_blob;
166179
size_t remaining = brcmfmac_clm_blob_len;
167180

168181
hdr = (struct brcmf_dload_data_le *)buf;
169-
hdr->flag = (1 << 12) | 2; /* DL_BEGIN */
170-
hdr->dload_type = 2; /* DL_TYPE_CLM */
182+
hdr->flag = BRCMF_DL_CRC_IN_HDR | BRCMF_DL_BEGIN;
183+
hdr->dload_type = BRCMF_DL_TYPE_CLM;
171184
hdr->crc = 0;
172185

173186
while (remaining > 0) {
174-
size_t transfer = chunk_size;
187+
size_t transfer = BRCMFMAC_CLM_CHUNK_SIZE;
175188
int ret;
176189

177190
if (remaining <= transfer) {
178191
transfer = remaining;
179-
hdr->flag |= 4; /* DL_END */
192+
hdr->flag |= BRCMF_DL_END;
180193
}
181194

182195
memcpy(hdr->data, current, transfer);
@@ -191,7 +204,7 @@ static int brcmfmac_process_clm_blob(struct brcmfmac_data *data)
191204

192205
current += transfer;
193206
remaining -= transfer;
194-
hdr->flag &= ~2u;
207+
hdr->flag &= ~BRCMF_DL_BEGIN;
195208
}
196209

197210
return 0;
@@ -227,23 +240,20 @@ static int brcmfmac_init(const struct device *dev)
227240
}
228241

229242
/*
230-
* CLM blob upload is required by chips whose firmware ships with no
231-
* built-in regulatory tables. Linux brcmfmac gates this on chip ID;
232-
* we mirror that gate so chips that don't need it (firmware refuses
233-
* the DL_TYPE_CLM iovar) don't fail init. Extend the list as new
234-
* chips are validated.
243+
* CLM blob upload. Chips that ship without built-in regulatory tables
244+
* (e.g. BCM43458F) require this; chips that have them (e.g. BCM43430A1)
245+
* still accept the iovar harmlessly. We always attempt the upload when
246+
* a blob is configured in the build via CONFIG_WIFI_BRCMFMAC_CLM_FILE;
247+
* an unconfigured build links an empty array (len==0) and we skip.
235248
*/
236-
bool needs_clm = (data->chip_id == 43430) || /* BCM43430A1 */
237-
(data->chip_id == 0xa9a6); /* CYW43439 */
238-
if (needs_clm) {
249+
if (brcmfmac_clm_blob_len > 0) {
239250
ret = brcmfmac_process_clm_blob(data);
240251
if (ret != 0) {
241252
LOG_ERR("CLM upload failed: %d", ret);
242253
return ret;
243254
}
244255
} else {
245-
LOG_DBG("CLM blob upload skipped for chip 0x%x rev %u",
246-
data->chip_id, data->chip_rev);
256+
LOG_DBG("CLM blob upload skipped (no blob configured)");
247257
}
248258

249259
int got = brcmfmac_bcdc_iovar_get(data, "cur_etheraddr",

drivers/wifi/brcmfmac/brcmfmac_fw_blob.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
6-
* brcmfmac firmware and NVRAM blob payload. The actual bytes are
7-
* generated by CMake from the corresponding files in hal_broadcom
8-
* (fetched via `west blobs fetch hal_broadcom`) and #include'd here.
6+
* brcmfmac firmware, NVRAM and (optional) CLM blob payloads. The actual
7+
* bytes are generated by CMake from the corresponding files in
8+
* hal_broadcom (fetched via `west blobs fetch hal_broadcom`) and
9+
* #include'd here. An unset CONFIG_WIFI_BRCMFMAC_CLM_FILE links an
10+
* empty CLM array and the driver skips the upload at runtime.
911
*/
1012

1113
const unsigned char brcmfmac_fw[] = {
@@ -17,3 +19,8 @@ const unsigned char brcmfmac_nvram[] = {
1719
#include "brcmfmac_nvram.inc"
1820
};
1921
const unsigned int brcmfmac_nvram_len = sizeof(brcmfmac_nvram);
22+
23+
const unsigned char brcmfmac_clm_blob[] = {
24+
#include "brcmfmac_clm_blob.inc"
25+
};
26+
const unsigned int brcmfmac_clm_blob_len = sizeof(brcmfmac_clm_blob);

drivers/wifi/brcmfmac/brcmfmac_priv.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@
5353
#define CID_TYPE_MASK 0xF0000000
5454
#define CID_TYPE_SHIFT 28
5555

56+
/* Broadcom/Cypress chipcommon[0] chip-ID values. The chip reports these
57+
* as the low 16 bits of CHIPID; brcmfmac uses them to select chip-specific
58+
* code paths (firmware blob, RAM layout, SOCRAM bank-3 quirk). Mirrors
59+
* Linux brcm_hw_ids.h.
60+
*/
61+
#define BRCM_CC_43430_CHIP_ID 0xa9a6 /* BCM43430 / BCM43436 */
62+
#define BRCM_CC_43439_CHIP_ID 0xa9af /* CYW43439 */
63+
#define BRCM_CC_4345_CHIP_ID 0x4345 /* BCM43458F */
64+
5665
/* BCMA core IDs (subset; full list in Linux include/linux/bcma/bcma.h). */
5766
#define BCMA_CORE_INTERNAL_MEM 0x80E /* SOCRAM */
5867
#define BCMA_CORE_80211 0x812 /* D11 MAC */
@@ -261,6 +270,18 @@ struct brcmf_event_msg_be {
261270
#define BRCMF_E_STATUS_NO_NETWORKS 3
262271
#define BRCMF_E_STATUS_PARTIAL 8
263272

273+
/* Flags for struct brcmf_dload_data_le (Linux brcmfmac/fwil_types.h
274+
* enum brcmf_dload_data_flag). The chip expects DL_BEGIN on the first
275+
* chunk and DL_END on the last; bit 12 (CRC-supplied) is set unconditionally
276+
* since the header carries a (currently zero) CRC field.
277+
*/
278+
#define BRCMF_DL_BEGIN (1u << 1)
279+
#define BRCMF_DL_END (1u << 2)
280+
#define BRCMF_DL_CRC_IN_HDR (1u << 12)
281+
282+
/* dload_type values (Linux brcmfmac/fwil_types.h enum brcmf_dload_type). */
283+
#define BRCMF_DL_TYPE_CLM 2
284+
264285
struct brcmf_dload_data_le {
265286
uint16_t flag;
266287
uint16_t dload_type;

drivers/wifi/brcmfmac/brcmfmac_sdio.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,10 @@ int brcmfmac_sdio_fw_upload(struct brcmfmac_data *data)
331331

332332
int brcmfmac_sdio_nvram_upload(struct brcmfmac_data *data)
333333
{
334-
static uint8_t nvram_buf[2048] __aligned(CONFIG_DCACHE_LINE_SIZE);
334+
/* Sized to fit the largest NVRAM currently shipped in linux-firmware
335+
* (3099 bytes after the footer); rounds up to 4 KiB.
336+
*/
337+
static uint8_t nvram_buf[4096] __aligned(CONFIG_DCACHE_LINE_SIZE);
335338
int stripped = brcmfmac_sdio_nvram_strip(brcmfmac_nvram, brcmfmac_nvram_len,
336339
nvram_buf, sizeof(nvram_buf));
337340
if (stripped < 0) {

0 commit comments

Comments
 (0)