summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fuzzey <martin.fuzzey@flowbird.group>2021-08-30 18:26:44 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-18 21:16:00 +0300
commitd63343e5aa173264082a3912c38684afb3721097 (patch)
tree10b0a345648ccfd8073957d91603b5762fb1ea50
parent60cbc288f8f3facc9e76e96d6e58dce4a2eb4150 (diff)
downloadlinux-d63343e5aa173264082a3912c38684afb3721097.tar.xz
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: 716b840c7641 ("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>
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_main.c16
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c3
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h2
3 files changed, 18 insertions, 3 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index d98483298555..143224a3802b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -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_*.
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 891fd5f0fa76..a25742a54598 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -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);
}
}
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 0f535850a383..a3e4fd5bd3e9 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -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