Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH wireless-next 0/4] wifi: cw1200: add XRadio XR819 support
@ 2026-11-02 17:15 Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 1/4] wifi: cw1200: don't update the beacon in station mode Pablo Mazzini
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Pablo Mazzini @ 2026-11-02 17:15 UTC (permalink / raw)
  To: linux-wireless; +Cc: Pablo Mazzini, Ulf Hansson, linux-mmc, linux-kernel

The XRadio XR819 SDIO Wi-Fi chip, used on the PocketBook Verse and on
boards like the Orange Pi Zero, is a CW1x60 derivative. cw1200 drives
it with a bootloader stage and two firmware differences: channel switch
and join. Patch 2 moves the per-chip firmware into a table first.

Tested on a PocketBook Verse: scan, WPA2-PSK, DHCP and ping.

Pablo Mazzini (4):
  wifi: cw1200: don't update the beacon in station mode
  wifi: cw1200: describe the chips in a table
  wifi: cw1200: handle the XR819 channel switch and join
  wifi: cw1200: add XRadio XR819 support

 drivers/net/wireless/st/cw1200/Kconfig       |   3 +-
 drivers/net/wireless/st/cw1200/cw1200.h      |   3 +-
 drivers/net/wireless/st/cw1200/cw1200_sdio.c |  13 +-
 drivers/net/wireless/st/cw1200/fwio.c        | 121 +++++++++++++------
 drivers/net/wireless/st/cw1200/fwio.h        |  15 ++-
 drivers/net/wireless/st/cw1200/main.c        |   2 +-
 drivers/net/wireless/st/cw1200/sta.c         |  12 +-
 drivers/net/wireless/st/cw1200/wsm.c         |   3 +-
 include/linux/mmc/sdio_ids.h                 |   1 +
 9 files changed, 126 insertions(+), 47 deletions(-)


base-commit: 2c50cd5d10e8723797f28c7978f1f61688e0c0d2
-- 
2.52.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH wireless-next 1/4] wifi: cw1200: don't update the beacon in station mode
  2026-11-02 17:15 [PATCH wireless-next 0/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
@ 2026-11-02 17:16 ` Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 2/4] wifi: cw1200: describe the chips in a table Pablo Mazzini
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Mazzini @ 2026-11-02 17:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Pablo Mazzini, linux-kernel

A station has no beacon. The XR819 firmware never confirms the
UPDATE_IE request, so the command times out after association.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/net/wireless/st/cw1200/sta.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/st/cw1200/sta.c b/drivers/net/wireless/st/cw1200/sta.c
index 5d8eaa700779..f3f31aa52499 100644
--- a/drivers/net/wireless/st/cw1200/sta.c
+++ b/drivers/net/wireless/st/cw1200/sta.c
@@ -1744,7 +1744,9 @@ void cw1200_set_cts_work(struct work_struct *work)
 
 	wsm_write_mib(priv, WSM_MIB_ID_NON_ERP_PROTECTION,
 		      &use_cts_prot, sizeof(use_cts_prot));
-	wsm_update_ie(priv, &update_ie);
+	/* A station has no beacon to update */
+	if (priv->mode != NL80211_IFTYPE_STATION)
+		wsm_update_ie(priv, &update_ie);
 
 	return;
 }
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH wireless-next 2/4] wifi: cw1200: describe the chips in a table
  2026-11-02 17:15 [PATCH wireless-next 0/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 1/4] wifi: cw1200: don't update the beacon in station mode Pablo Mazzini
@ 2026-11-02 17:16 ` Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 3/4] wifi: cw1200: handle the XR819 channel switch and join Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 4/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Mazzini @ 2026-11-02 17:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Pablo Mazzini, linux-kernel

Replace the firmware selection switch with a table keyed by the
silicon revision, so per-chip properties can be added in one place.
The SDD path becomes const to take the table's names.

No functional change.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/net/wireless/st/cw1200/cw1200.h |  3 +-
 drivers/net/wireless/st/cw1200/fwio.c   | 67 +++++++++++++++----------
 drivers/net/wireless/st/cw1200/fwio.h   |  6 +++
 drivers/net/wireless/st/cw1200/main.c   |  2 +-
 4 files changed, 49 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/cw1200.h b/drivers/net/wireless/st/cw1200/cw1200.h
index 48f808cdc1cb..8867b2c94c8d 100644
--- a/drivers/net/wireless/st/cw1200/cw1200.h
+++ b/drivers/net/wireless/st/cw1200/cw1200.h
@@ -117,10 +117,11 @@ struct cw1200_common {
 		CW1200_HW_REV_CUT22 = 22,
 		CW1X60_HW_REV       = 40,
 	} hw_revision;
+	const struct cw1200_chip	*chip;
 	int                             hw_refclk;
 	bool				hw_have_5ghz;
 	const struct firmware		*sdd;
-	char                            *sdd_path;
+	const char			*sdd_path;
 
 	struct cw1200_debug_priv	*debug;
 
diff --git a/drivers/net/wireless/st/cw1200/fwio.c b/drivers/net/wireless/st/cw1200/fwio.c
index 2a03dc533b6a..6601aec1f231 100644
--- a/drivers/net/wireless/st/cw1200/fwio.c
+++ b/drivers/net/wireless/st/cw1200/fwio.c
@@ -48,6 +48,41 @@ static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
 	return hw_type;
 }
 
+static const struct cw1200_chip cw1200_chips[] = {
+	{
+		.revision = CW1200_HW_REV_CUT10,
+		.firmware = FIRMWARE_CUT10,
+		.sdd = SDD_FILE_10,
+	}, {
+		.revision = CW1200_HW_REV_CUT11,
+		.firmware = FIRMWARE_CUT11,
+		.sdd = SDD_FILE_11,
+	}, {
+		.revision = CW1200_HW_REV_CUT20,
+		.firmware = FIRMWARE_CUT20,
+		.sdd = SDD_FILE_20,
+	}, {
+		.revision = CW1200_HW_REV_CUT22,
+		.firmware = FIRMWARE_CUT22,
+		.sdd = SDD_FILE_22,
+	}, {
+		.revision = CW1X60_HW_REV,
+		.firmware = FIRMWARE_CW1X60,
+		.sdd = SDD_FILE_CW1X60,
+	},
+};
+
+static const struct cw1200_chip *cw1200_find_chip(int revision)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(cw1200_chips); i++)
+		if (cw1200_chips[i].revision == revision)
+			return &cw1200_chips[i];
+
+	return NULL;
+}
+
 static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
 {
 	int ret, block, num_blocks;
@@ -90,36 +125,14 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
 			goto exit; \
 	} while (0)
 
-	switch (priv->hw_revision) {
-	case CW1200_HW_REV_CUT10:
-		fw_path = FIRMWARE_CUT10;
-		if (!priv->sdd_path)
-			priv->sdd_path = SDD_FILE_10;
-		break;
-	case CW1200_HW_REV_CUT11:
-		fw_path = FIRMWARE_CUT11;
-		if (!priv->sdd_path)
-			priv->sdd_path = SDD_FILE_11;
-		break;
-	case CW1200_HW_REV_CUT20:
-		fw_path = FIRMWARE_CUT20;
-		if (!priv->sdd_path)
-			priv->sdd_path = SDD_FILE_20;
-		break;
-	case CW1200_HW_REV_CUT22:
-		fw_path = FIRMWARE_CUT22;
-		if (!priv->sdd_path)
-			priv->sdd_path = SDD_FILE_22;
-		break;
-	case CW1X60_HW_REV:
-		fw_path = FIRMWARE_CW1X60;
-		if (!priv->sdd_path)
-			priv->sdd_path = SDD_FILE_CW1X60;
-		break;
-	default:
+	priv->chip = cw1200_find_chip(priv->hw_revision);
+	if (!priv->chip) {
 		pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
 		return -EINVAL;
 	}
+	fw_path = priv->chip->firmware;
+	if (!priv->sdd_path)
+		priv->sdd_path = priv->chip->sdd;
 
 	/* Initialize common registers */
 	APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
diff --git a/drivers/net/wireless/st/cw1200/fwio.h b/drivers/net/wireless/st/cw1200/fwio.h
index c287160a492e..e97cbcd54e57 100644
--- a/drivers/net/wireless/st/cw1200/fwio.h
+++ b/drivers/net/wireless/st/cw1200/fwio.h
@@ -26,6 +26,12 @@
 #define SDD_FILE_11		"sdd_11.bin"
 #define SDD_FILE_10		"sdd_10.bin"
 
+struct cw1200_chip {
+	int revision;
+	const char *firmware;
+	const char *sdd;
+};
+
 int cw1200_load_firmware(struct cw1200_common *priv);
 
 /* SDD definitions */
diff --git a/drivers/net/wireless/st/cw1200/main.c b/drivers/net/wireless/st/cw1200/main.c
index 5d569eeb353f..793471acbfb6 100644
--- a/drivers/net/wireless/st/cw1200/main.c
+++ b/drivers/net/wireless/st/cw1200/main.c
@@ -541,7 +541,7 @@ int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
 	if (cw1200_refclk)
 		priv->hw_refclk = cw1200_refclk;
 
-	priv->sdd_path = (char *)sdd_path;
+	priv->sdd_path = sdd_path;
 	if (cw1200_sdd_path)
 		priv->sdd_path = cw1200_sdd_path;
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH wireless-next 3/4] wifi: cw1200: handle the XR819 channel switch and join
  2026-11-02 17:15 [PATCH wireless-next 0/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 1/4] wifi: cw1200: don't update the beacon in station mode Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 2/4] wifi: cw1200: describe the chips in a table Pablo Mazzini
@ 2026-11-02 17:16 ` Pablo Mazzini
  2026-11-02 17:16 ` [PATCH wireless-next 4/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Mazzini @ 2026-11-02 17:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Pablo Mazzini, linux-kernel

The XR819, detected as CW1x60, asserts on SWITCH_CHANNEL while idle
and only joins synchronously, confirming after up to 5 s. Keep the
channel for scan and join, as the vendor driver does, drop the
asynchronous join flags, and allow 7 s for the join.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/net/wireless/st/cw1200/fwio.c | 2 ++
 drivers/net/wireless/st/cw1200/fwio.h | 2 ++
 drivers/net/wireless/st/cw1200/sta.c  | 8 +++++---
 drivers/net/wireless/st/cw1200/wsm.c  | 3 ++-
 4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/fwio.c b/drivers/net/wireless/st/cw1200/fwio.c
index 6601aec1f231..1a68ef6ed2fa 100644
--- a/drivers/net/wireless/st/cw1200/fwio.c
+++ b/drivers/net/wireless/st/cw1200/fwio.c
@@ -69,6 +69,8 @@ static const struct cw1200_chip cw1200_chips[] = {
 		.revision = CW1X60_HW_REV,
 		.firmware = FIRMWARE_CW1X60,
 		.sdd = SDD_FILE_CW1X60,
+		.sync_join = true,
+		.no_switch_channel = true,
 	},
 };
 
diff --git a/drivers/net/wireless/st/cw1200/fwio.h b/drivers/net/wireless/st/cw1200/fwio.h
index e97cbcd54e57..9925d4bcedda 100644
--- a/drivers/net/wireless/st/cw1200/fwio.h
+++ b/drivers/net/wireless/st/cw1200/fwio.h
@@ -30,6 +30,8 @@ struct cw1200_chip {
 	int revision;
 	const char *firmware;
 	const char *sdd;
+	bool sync_join;		/* no asynchronous join */
+	bool no_switch_channel;	/* scan and join pass the channel */
 };
 
 int cw1200_load_firmware(struct cw1200_common *priv);
diff --git a/drivers/net/wireless/st/cw1200/sta.c b/drivers/net/wireless/st/cw1200/sta.c
index f3f31aa52499..eeb2bf56edff 100644
--- a/drivers/net/wireless/st/cw1200/sta.c
+++ b/drivers/net/wireless/st/cw1200/sta.c
@@ -349,8 +349,10 @@ int cw1200_config(struct ieee80211_hw *dev, int radio_idx, u32 changed)
 		pr_debug("[STA] Freq %d (wsm ch: %d).\n",
 			 ch->center_freq, ch->hw_value);
 
-		/* __cw1200_flush() implicitly locks tx, if successful */
-		if (!__cw1200_flush(priv, false)) {
+		if (priv->chip->no_switch_channel) {
+			priv->channel = ch;
+		} else if (!__cw1200_flush(priv, false)) {
+			/* __cw1200_flush() implicitly locks tx, if successful */
 			if (!wsm_switch_channel(priv, &channel)) {
 				ret = wait_event_timeout(priv->channel_switch_done,
 							 !priv->channel_switch_in_progress,
@@ -1304,7 +1306,7 @@ static void cw1200_do_join(struct cw1200_common *priv)
 	}
 
 	/* Enable asynchronous join calls */
-	if (!priv->vif->cfg.ibss_joined) {
+	if (!priv->vif->cfg.ibss_joined && !priv->chip->sync_join) {
 		join.flags |= WSM_JOIN_FLAGS_FORCE;
 		join.flags |= WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND;
 	}
diff --git a/drivers/net/wireless/st/cw1200/wsm.c b/drivers/net/wireless/st/cw1200/wsm.c
index d6529e5b73b2..6b0b333620ee 100644
--- a/drivers/net/wireless/st/cw1200/wsm.c
+++ b/drivers/net/wireless/st/cw1200/wsm.c
@@ -20,6 +20,7 @@
 #include "debug.h"
 
 #define WSM_CMD_TIMEOUT		(2 * HZ) /* With respect to interrupt loss */
+#define WSM_CMD_JOIN_TIMEOUT	(7 * HZ) /* A synchronous join takes up to 5 s */
 #define WSM_CMD_START_TIMEOUT	(7 * HZ)
 #define WSM_CMD_RESET_TIMEOUT	(3 * HZ) /* 2 sec. timeout was observed.   */
 #define WSM_CMD_MAX_TIMEOUT	(3 * HZ)
@@ -445,7 +446,7 @@ int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
 
 	priv->tx_burst_idx = -1;
 	ret = wsm_cmd_send(priv, buf, &resp,
-			   WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
+			   WSM_JOIN_REQ_ID, WSM_CMD_JOIN_TIMEOUT);
 	/* TODO:  Update state based on resp.min|max_power_level */
 
 	priv->join_complete_status = resp.status;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH wireless-next 4/4] wifi: cw1200: add XRadio XR819 support
  2026-11-02 17:15 [PATCH wireless-next 0/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
                   ` (2 preceding siblings ...)
  2026-11-02 17:16 ` [PATCH wireless-next 3/4] wifi: cw1200: handle the XR819 channel switch and join Pablo Mazzini
@ 2026-11-02 17:16 ` Pablo Mazzini
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Mazzini @ 2026-11-02 17:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Pablo Mazzini, Ulf Hansson, linux-mmc, linux-kernel

The XR819 uses the ST-E SDIO vendor ID with device ID 0x2281 and
reports itself as a CW1x60. It starts from a bootloader written into
its memory, then takes the usual firmware download. Its modules run
from a 24 MHz reference clock.

Give the CW1x60 entry the XR819 bootloader and firmware, and load the
bootloader instead of the NOP instruction.

Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
 drivers/net/wireless/st/cw1200/Kconfig       |  3 +-
 drivers/net/wireless/st/cw1200/cw1200_sdio.c | 13 ++++-
 drivers/net/wireless/st/cw1200/fwio.c        | 58 ++++++++++++++++----
 drivers/net/wireless/st/cw1200/fwio.h        |  7 ++-
 include/linux/mmc/sdio_ids.h                 |  1 +
 5 files changed, 66 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/Kconfig b/drivers/net/wireless/st/cw1200/Kconfig
index 03575e9894bb..9404e318137c 100644
--- a/drivers/net/wireless/st/cw1200/Kconfig
+++ b/drivers/net/wireless/st/cw1200/Kconfig
@@ -3,7 +3,8 @@ config CW1200
 	tristate "CW1200 WLAN support"
 	depends on MAC80211 && CFG80211
 	help
-	  This is a driver for the ST-E CW1100 & CW1200 WLAN chipsets.
+	  This is a driver for the ST-E CW1100 & CW1200 and the XRadio
+	  XR819 WLAN chipsets.
 	  This option just enables the driver core, see below for
 	  specific bus support.
 
diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c
index 2b6afe221268..3db937785cab 100644
--- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c
@@ -35,6 +35,12 @@ static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
 	.sdd_file = "sdd_sagrad_1091_1098.bin",
 };
 
+/* XRadio XR819 modules, with a 24 MHz reference clock */
+static const struct cw1200_platform_data_sdio xr819_platform_data = {
+	.ref_clk = 24000,
+	.have_5ghz = false,
+};
+
 /* Allow platform data to be overridden */
 static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
 
@@ -51,6 +57,8 @@ struct hwbus_priv {
 
 static const struct sdio_device_id cw1200_sdio_ids[] = {
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_XR819),
+	  .driver_data = (kernel_ulong_t)&xr819_platform_data },
 	{ /* end: all zeroes */			},
 };
 MODULE_DEVICE_TABLE(sdio, cw1200_sdio_ids);
@@ -295,7 +303,10 @@ static int cw1200_sdio_probe(struct sdio_func *func,
 
 	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
-	self->pdata = global_plat_data; /* FIXME */
+	if (id->driver_data)
+		self->pdata = (const void *)id->driver_data;
+	else
+		self->pdata = global_plat_data; /* FIXME */
 	self->func = func;
 	sdio_set_drvdata(func, self);
 	sdio_claim_host(func);
diff --git a/drivers/net/wireless/st/cw1200/fwio.c b/drivers/net/wireless/st/cw1200/fwio.c
index 1a68ef6ed2fa..6b885fd717db 100644
--- a/drivers/net/wireless/st/cw1200/fwio.c
+++ b/drivers/net/wireless/st/cw1200/fwio.c
@@ -66,9 +66,10 @@ static const struct cw1200_chip cw1200_chips[] = {
 		.firmware = FIRMWARE_CUT22,
 		.sdd = SDD_FILE_22,
 	}, {
-		.revision = CW1X60_HW_REV,
-		.firmware = FIRMWARE_CW1X60,
-		.sdd = SDD_FILE_CW1X60,
+		.revision = CW1X60_HW_REV,	/* XRadio XR819 */
+		.bootloader = BOOTLOADER_XR819,
+		.firmware = FIRMWARE_XR819,
+		.sdd = SDD_FILE_XR819,
 		.sync_join = true,
 		.no_switch_channel = true,
 	},
@@ -85,6 +86,38 @@ static const struct cw1200_chip *cw1200_find_chip(int revision)
 	return NULL;
 }
 
+/* The bootloader is written word by word into the AHB memory */
+static int cw1200_load_bootloader(struct cw1200_common *priv)
+{
+	const struct firmware *bootloader;
+	const __le32 *data;
+	u32 addr = 0x08000000;
+	size_t i;
+	int ret;
+
+	ret = request_firmware(&bootloader, priv->chip->bootloader, priv->pdev);
+	if (ret) {
+		pr_err("Can't load bootloader file %s.\n", priv->chip->bootloader);
+		return ret;
+	}
+
+	data = (const __le32 *)bootloader->data;
+	for (i = 0; i < bootloader->size / 4; i++, addr += 4) {
+		ret = cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID,
+					  addr);
+		if (!ret)
+			ret = cw1200_reg_write_32(priv, ST90TDS_AHB_DPORT_REG_ID,
+						  le32_to_cpu(data[i]));
+		if (ret) {
+			pr_err("Can't write bootloader.\n");
+			break;
+		}
+	}
+
+	release_firmware(bootloader);
+	return ret;
+}
+
 static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
 {
 	int ret, block, num_blocks;
@@ -136,6 +169,12 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
 	if (!priv->sdd_path)
 		priv->sdd_path = priv->chip->sdd;
 
+	if (priv->chip->bootloader) {
+		ret = cw1200_load_bootloader(priv);
+		if (ret)
+			return ret;
+	}
+
 	/* Initialize common registers */
 	APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
 	APB_WRITE(DOWNLOAD_PUT_REG, 0);
@@ -143,9 +182,11 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
 	APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
 	APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
 
-	/* Write the NOP Instruction */
-	REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
-	REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
+	/* Write the NOP Instruction, unless the bootloader runs instead */
+	if (!priv->chip->bootloader) {
+		REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
+		REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
+	}
 
 	/* Release CPU from RESET */
 	REG_READ(ST90TDS_CONFIG_REG_ID, val32);
@@ -483,11 +524,6 @@ int cw1200_load_firmware(struct cw1200_common *priv)
 
 	switch (priv->hw_type)  {
 	case HIF_8601_SILICON:
-		if (priv->hw_revision == CW1X60_HW_REV) {
-			pr_err("Can't handle CW1160/1260 firmware load yet.\n");
-			ret = -ENOTSUPP;
-			goto out;
-		}
 		ret = cw1200_load_firmware_cw1200(priv);
 		break;
 	default:
diff --git a/drivers/net/wireless/st/cw1200/fwio.h b/drivers/net/wireless/st/cw1200/fwio.h
index 9925d4bcedda..fb66d564c304 100644
--- a/drivers/net/wireless/st/cw1200/fwio.h
+++ b/drivers/net/wireless/st/cw1200/fwio.h
@@ -14,13 +14,13 @@
 #ifndef FWIO_H_INCLUDED
 #define FWIO_H_INCLUDED
 
-#define BOOTLOADER_CW1X60       "boot_cw1x60.bin"
-#define FIRMWARE_CW1X60		"wsm_cw1x60.bin"
+#define BOOTLOADER_XR819	"xr819/boot_xr819.bin"
+#define FIRMWARE_XR819		"xr819/fw_xr819.bin"
 #define FIRMWARE_CUT22		"wsm_22.bin"
 #define FIRMWARE_CUT20		"wsm_20.bin"
 #define FIRMWARE_CUT11		"wsm_11.bin"
 #define FIRMWARE_CUT10		"wsm_10.bin"
-#define SDD_FILE_CW1X60		"sdd_cw1x60.bin"
+#define SDD_FILE_XR819		"xr819/sdd_xr819.bin"
 #define SDD_FILE_22		"sdd_22.bin"
 #define SDD_FILE_20		"sdd_20.bin"
 #define SDD_FILE_11		"sdd_11.bin"
@@ -28,6 +28,7 @@
 
 struct cw1200_chip {
 	int revision;
+	const char *bootloader;	/* NULL: write the NOP instruction */
 	const char *firmware;
 	const char *sdd;
 	bool sync_join;		/* no asynchronous join */
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index dfffda3d8002..35789be747a5 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -27,6 +27,7 @@
 
 #define SDIO_VENDOR_ID_STE			0x0020
 #define SDIO_DEVICE_ID_STE_CW1200		0x2280
+#define SDIO_DEVICE_ID_STE_XR819		0x2281
 
 #define SDIO_VENDOR_ID_INTEL			0x0089
 #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX	0x1402
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-02 17:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-02 17:15 [PATCH wireless-next 0/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini
2026-11-02 17:16 ` [PATCH wireless-next 1/4] wifi: cw1200: don't update the beacon in station mode Pablo Mazzini
2026-11-02 17:16 ` [PATCH wireless-next 2/4] wifi: cw1200: describe the chips in a table Pablo Mazzini
2026-11-02 17:16 ` [PATCH wireless-next 3/4] wifi: cw1200: handle the XR819 channel switch and join Pablo Mazzini
2026-11-02 17:16 ` [PATCH wireless-next 4/4] wifi: cw1200: add XRadio XR819 support Pablo Mazzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox