The AR9271 PA calibration has been running with its last five register writes dropped since the RMW buffer was added. ar9271_hw_pa_cal() queues exactly 15 read-modify-writes, which fills the buffer, and ath9k_reg_rmw_buffer() sizes that flush with sizeof(struct register_write), 8 bytes, instead of sizeof(struct register_rmw), 12 bytes. The firmware gets 120 of the 180 bytes and applies only the first 10. Fixing the size alone kills the device. The command becomes 8 (HTC) + 4 (WMI) + 180 = 192 bytes, three full 64-byte USB packets, and the firmware ends a command only on a short packet (usb_reg_out_patch() in open-ath9k-htc-firmware). The 192-byte command is never delivered: the device stops answering WMI and stays dead through a warm reboot until power is removed. An AR9271 hangs this way on the first interface open, with the linux-firmware 1.4.0 blob and with an open-firmware build alike. So cap the buffer at 14 entries as well. A command of n entries is 12 * (n + 1) bytes, a multiple of 64 only at n = 15 within the buffer's reach. The next largest RMW batch, ath9k_hw_4k_set_gain(), queues at most 14 entries, 180 bytes, and a register write batch is 8n + 12 bytes, never a multiple of 64. The PA calibration then goes out as 14 + 1 entries and all 15 writes reach the chip. AR9271_AN_RF2G6_OFFS then reads 30 on 40 of 40 opens, where the truncated command gave 32 on 78 of 80; a firmware with fixed reassembly, given the full 15-entry command, gave 30 on 19 of 20. The on-air effect is not measured yet. With the cap, 120 interface opens ran clean: 60 with this patch, 20 of them on the linux-firmware 1.4.0 blob and 20 on a second AR9271, and 60 with a bench build of the same wire lengths. Fixes: 8badb50cfab6 ("ath9k_htc: add new WMI_REG_RMW_CMDID command") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Nerijus Bendžiūnas --- Changes in v3: - v2 said no caller fills the buffer; ar9271_hw_pa_cal() does, on every AR9271 reset. - Cap MAX_RMW_CMD_NUMBER at 14 in the same patch: the corrected size alone yields a 192-byte command the firmware never delivers. - Assisted-by in the form Documentation/process/coding-assistants.rst now asks for. Changes in v2: - Add Assisted-by, rewrite the commit message, rebase onto ath-next. drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/wmi.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 6de78ae85726..0b49d2cc99f0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -405,7 +405,7 @@ static void ath9k_reg_rmw_buffer(void *hw_priv, if (priv->wmi->multi_rmw_idx == MAX_RMW_CMD_NUMBER) { r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID, (u8 *) &priv->wmi->multi_rmw, - sizeof(struct register_write) * priv->wmi->multi_rmw_idx, + sizeof(struct register_rmw) * priv->wmi->multi_rmw_idx, (u8 *) &rsp_status, sizeof(rsp_status), 100); if (unlikely(r)) { diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 5c3b710b8f31..256f46098a6b 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -126,7 +126,8 @@ enum wmi_event_id { }; #define MAX_CMD_NUMBER 62 -#define MAX_RMW_CMD_NUMBER 15 +/* 15 entries make 192 bytes, three full USB packets: never delivered. */ +#define MAX_RMW_CMD_NUMBER 14 struct register_write { __be32 reg; -- 2.55.0