rsi: fix occasional initialisation failure with BT coex

commit 9b14ed6e11b72dd4806535449ca6c6962cb2369d upstream.

When BT coexistence is enabled (eg oper mode 13, which is the default)
the initialisation on startup sometimes silently fails.

In a normal initialisation we see
	usb 1-1.3: Product: Wireless USB Network Module
	usb 1-1.3: Manufacturer: Redpine Signals, Inc.
	usb 1-1.3: SerialNumber: 000000000001
	rsi_91x: rsi_probe: Initialized os intf ops
	rsi_91x: rsi_load_9116_firmware: Loading chunk 0
	rsi_91x: rsi_load_9116_firmware: Loading chunk 1
	rsi_91x: rsi_load_9116_firmware: Loading chunk 2
	rsi_91x: Max Stations Allowed = 1

But sometimes the last log is missing and the wlan net device is
not created.

Running a userspace loop that resets the hardware via a GPIO shows the
problem occurring ~5/100 resets.

The problem does not occur in oper mode 1 (wifi only).

Adding logs shows that the initialisation state machine requests a MAC
reset via rsi_send_reset_mac() but the firmware does not reply, leading
to the initialisation sequence being incomplete.

Fix this by delaying attaching the BT adapter until the wifi
initialisation has completed.

With this applied I have done > 300 reset loops with no errors.

Fixes: 716b840c76 ("rsi: handle BT traffic in driver")
Signed-off-by: Martin Fuzzey <martin.fuzzey@flowbird.group>
CC: stable@vger.kernel.org
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1630337206-12410-2-git-send-email-martin.fuzzey@flowbird.group
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Martin Fuzzey 2021-08-30 17:26:44 +02:00 committed by Greg Kroah-Hartman
parent a194e9c721
commit 46752a7aed
3 changed files with 18 additions and 3 deletions

View File

@ -211,9 +211,10 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST];
if (bt_pkt_type == BT_CARD_READY_IND) {
rsi_dbg(INFO_ZONE, "BT Card ready recvd\n");
if (rsi_bt_ops.attach(common, &g_proto_ops))
rsi_dbg(ERR_ZONE,
"Failed to attach BT module\n");
if (common->fsm_state == FSM_MAC_INIT_DONE)
rsi_attach_bt(common);
else
common->bt_defer_attach = true;
} else {
if (common->bt_adapter)
rsi_bt_ops.recv_pkt(common->bt_adapter,
@ -278,6 +279,15 @@ void rsi_set_bt_context(void *priv, void *bt_context)
}
#endif
void rsi_attach_bt(struct rsi_common *common)
{
#ifdef CONFIG_RSI_COEX
if (rsi_bt_ops.attach(common, &g_proto_ops))
rsi_dbg(ERR_ZONE,
"Failed to attach BT module\n");
#endif
}
/**
* rsi_91x_init() - This function initializes os interface operations.
* @oper_mode: One of DEV_OPMODE_*.

View File

@ -2071,6 +2071,9 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
if (common->reinit_hw) {
complete(&common->wlan_init_completion);
} else {
if (common->bt_defer_attach)
rsi_attach_bt(common);
return rsi_mac80211_attach(common);
}
}

View File

@ -320,6 +320,7 @@ struct rsi_common {
struct ieee80211_vif *roc_vif;
bool eapol4_confirm;
bool bt_defer_attach;
void *bt_adapter;
struct cfg80211_scan_request *hwscan;
@ -401,5 +402,6 @@ struct rsi_host_intf_ops {
enum rsi_host_intf rsi_get_host_intf(void *priv);
void rsi_set_bt_context(void *priv, void *bt_context);
void rsi_attach_bt(struct rsi_common *common);
#endif