From: Siva Rebbagondla <[email protected]>
This set of patches consists wowlan debug support and common fixes
for redpine wireless driver
Siva Rebbagondla (5):
rsi: Add debug support for wowlan wakeup confirmation
rsi: add hci detach for hibernation and poweroff
rsi: fix wowlan wakeup issue for hibernate(S4)
rsi: resolve power save issue after S4 resume
rsi: fix for wowlan wakeup failure
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 21 ++++++++++++++++++---
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 29 +++++++++++++++++++++++++++++
drivers/net/wireless/rsi/rsi_91x_sdio.c | 23 ++++++++++++++++++++---
drivers/net/wireless/rsi/rsi_91x_usb.c | 6 ++++++
drivers/net/wireless/rsi/rsi_main.h | 1 +
5 files changed, 74 insertions(+), 6 deletions(-)
--
2.5.5
From: Siva Rebbagondla <[email protected]>
When a wowlan magic-packet has received to wake up the device, currently
driver is not taking care of what kind of packet has received. This patch
will add debug support for wakeup reason in driver.
Signed-off-by: Siva Rebbagondla <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 4042414..4c2c776 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -2003,6 +2003,35 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
return -1;
rsi_send_beacon(common);
break;
+ case WOWLAN_WAKEUP_REASON:
+ rsi_dbg(ERR_ZONE, "\n\nWakeup Type: %x\n", msg[15]);
+ switch (msg[15]) {
+ case RSI_UNICAST_MAGIC_PKT:
+ rsi_dbg(ERR_ZONE,
+ "*** Wakeup for Unicast magic packet ***\n");
+ break;
+ case RSI_BROADCAST_MAGICPKT:
+ rsi_dbg(ERR_ZONE,
+ "*** Wakeup for Broadcast magic packet ***\n");
+ break;
+ case RSI_EAPOL_PKT:
+ rsi_dbg(ERR_ZONE,
+ "*** Wakeup for GTK renewal ***\n");
+ break;
+ case RSI_DISCONNECT_PKT:
+ rsi_dbg(ERR_ZONE,
+ "*** Wakeup for Disconnect ***\n");
+ break;
+ case RSI_HW_BMISS_PKT:
+ rsi_dbg(ERR_ZONE,
+ "*** Wakeup for HW Beacon miss ***\n");
+ break;
+ default:
+ rsi_dbg(ERR_ZONE,
+ "##### Un-intentional Wakeup #####\n");
+ break;
+ }
+ break;
case RX_DOT11_MGMT:
return rsi_mgmt_pkt_to_core(common, msg, msg_len);
default:
--
2.5.5
From: Siva Rebbagondla <[email protected]>
As we missed to detach HCI, while entering power off or hibernation,
an extra hci interface gets created whenever system is woken up, to
avoid this we added hci_detach() in rsi_disconnect(), rsi_freeze(),
and rsi_shutdown() functions which are invoked for these tests.
This patch fixes the issue
Signed-off-by: Siva Rebbagondla <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 21 +++++++++++++++++++--
drivers/net/wireless/rsi/rsi_91x_usb.c | 6 ++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index b412b65e..59ff778 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1131,7 +1131,12 @@ static void rsi_disconnect(struct sdio_func *pfunction)
rsi_mac80211_detach(adapter);
mdelay(10);
-
+#ifdef CONFIG_RSI_COEX
+ if (adapter->priv->coex_mode > 1 && adapter->priv->bt_adapter) {
+ rsi_bt_ops.detach(adapter->priv->bt_adapter);
+ adapter->priv->bt_adapter = NULL;
+ }
+#endif
/* Reset Chip */
rsi_reset_chip(adapter);
@@ -1308,6 +1313,13 @@ static int rsi_freeze(struct device *dev)
rsi_dbg(ERR_ZONE,
"##### Device can not wake up through WLAN\n");
+#ifdef CONFIG_RSI_COEX
+ if (common->coex_mode > 1 && common->bt_adapter) {
+ rsi_bt_ops.detach(common->bt_adapter);
+ common->bt_adapter = NULL;
+ }
+#endif
+
ret = rsi_sdio_disable_interrupts(pfunction);
if (sdev->write_fail)
@@ -1354,7 +1366,12 @@ static void rsi_shutdown(struct device *dev)
if (rsi_config_wowlan(adapter, wowlan))
rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n");
-
+#ifdef CONFIG_RSI_COEX
+ if (adapter->priv->coex_mode > 1 && adapter->priv->bt_adapter) {
+ rsi_bt_ops.detach(adapter->priv->bt_adapter);
+ adapter->priv->bt_adapter = NULL;
+ }
+#endif
rsi_sdio_disable_interrupts(sdev->pfunction);
if (sdev->write_fail)
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index f360690..be20fd1 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -816,6 +816,12 @@ static void rsi_disconnect(struct usb_interface *pfunction)
return;
rsi_mac80211_detach(adapter);
+#ifdef CONFIG_RSI_COEX
+ if (adapter->priv->coex_mode > 1 && adapter->priv->bt_adapter) {
+ rsi_bt_ops.detach(adapter->priv->bt_adapter);
+ adapter->priv->bt_adapter = NULL;
+ }
+#endif
rsi_reset_card(adapter);
rsi_deinit_usb_interface(adapter);
rsi_91x_deinit(adapter);
--
2.5.5
From: Siva Rebbagondla <[email protected]>
At SDIO restore ieee80211_restart_hw() is getting called to restart all
MAC operations. This step is not required.
Returning 1 from mac80211_resume() will serve this purpose.
Signed-off-by: Siva Rebbagondla <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 8 ++++++--
drivers/net/wireless/rsi/rsi_91x_sdio.c | 1 -
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index aded1ae..8d1282f 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1938,8 +1938,12 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw)
rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__);
- if (common->hibernate_resume)
- return 0;
+ if (common->hibernate_resume) {
+ /* Device need a complete restart of all MAC operations.
+ * returning 1 will serve this purpose.
+ */
+ return 1;
+ }
mutex_lock(&common->mutex);
rsi_send_wowlan_request(common, 0, 0);
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 59ff778..3375d64 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1395,7 +1395,6 @@ static int rsi_restore(struct device *dev)
common->iface_down = true;
adapter->sc_nvifs = 0;
- ieee80211_restart_hw(adapter->hw);
common->wow_flags = 0;
common->iface_down = false;
--
2.5.5
From: Siva Rebbagondla <[email protected]>
We are redownloading the firmware after S4 restore and observed in
stress test that mac80211 sometimes gives power save request after
resume which causes the firmware in bad state. mac_ops_resumed flag
is added to skip that request until initialisation is done and Keeping
power save state is NONE.
Signed-off-by: Siva Rebbagondla <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 9 ++++++++-
drivers/net/wireless/rsi/rsi_91x_sdio.c | 1 +
drivers/net/wireless/rsi/rsi_main.h | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 8d1282f..7bc8da6 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -239,6 +239,7 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss = &vif->bss_conf;
rsi_dbg(INFO_ZONE, "***** Hardware scan start *****\n");
+ common->mac_ops_resumed = false;
if (common->fsm_state != FSM_MAC_INIT_DONE)
return -ENODEV;
@@ -370,6 +371,10 @@ static void rsi_mac80211_tx(struct ieee80211_hw *hw,
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
+ struct ieee80211_hdr *wlh = (struct ieee80211_hdr *)skb->data;
+
+ if (ieee80211_is_auth(wlh->frame_control))
+ common->mac_ops_resumed = false;
rsi_core_xmit(common, skb);
}
@@ -677,7 +682,8 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
}
/* Power save parameters */
- if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if ((changed & IEEE80211_CONF_CHANGE_PS) &&
+ !common->mac_ops_resumed) {
struct ieee80211_vif *vif, *sta_vif = NULL;
unsigned long flags;
int i, set_ps = 1;
@@ -1939,6 +1945,7 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw)
rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__);
if (common->hibernate_resume) {
+ common->mac_ops_resumed = true;
/* Device need a complete restart of all MAC operations.
* returning 1 will serve this purpose.
*/
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 3375d64..7e0edc7 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1395,6 +1395,7 @@ static int rsi_restore(struct device *dev)
common->iface_down = true;
adapter->sc_nvifs = 0;
+ adapter->ps_state = PS_NONE;
common->wow_flags = 0;
common->iface_down = false;
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 4dc0c01..35d13f3 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -311,6 +311,7 @@ struct rsi_common {
struct cfg80211_scan_request *hwscan;
struct rsi_bgscan_params bgscan;
u8 bgscan_en;
+ u8 mac_ops_resumed;
};
struct eepromrw_info {
--
2.5.5
From: Siva Rebbagondla <[email protected]>
During wowlan regression tests, sometimes radio is not waking up for wowlan
packet in coex mode. This is because of power save is enabled by default
in case of coex mode greater than one. Hence, disable power save in coex
mode to avoid radio loss.
Signed-off-by: Siva Rebbagondla <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 7bc8da6..3fd2571 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1901,6 +1901,10 @@ int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan)
return 0;
}
rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers);
+
+ if (common->coex_mode > 1)
+ rsi_disable_ps(adapter, adapter->vifs[0]);
+
rsi_send_wowlan_request(common, triggers, 1);
/**
--
2.5.5
Siva Rebbagondla <[email protected]> writes:
> From: Siva Rebbagondla <[email protected]>
>
> As we missed to detach HCI, while entering power off or hibernation,
> an extra hci interface gets created whenever system is woken up, to
> avoid this we added hci_detach() in rsi_disconnect(), rsi_freeze(),
> and rsi_shutdown() functions which are invoked for these tests.
> This patch fixes the issue
>
> Signed-off-by: Siva Rebbagondla <[email protected]>
> ---
> drivers/net/wireless/rsi/rsi_91x_sdio.c | 21 +++++++++++++++++++--
> drivers/net/wireless/rsi/rsi_91x_usb.c | 6 ++++++
> 2 files changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
> index b412b65e..59ff778 100644
> --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
> +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
> @@ -1131,7 +1131,12 @@ static void rsi_disconnect(struct sdio_func *pfunction)
>
> rsi_mac80211_detach(adapter);
> mdelay(10);
> -
> +#ifdef CONFIG_RSI_COEX
> + if (adapter->priv->coex_mode > 1 && adapter->priv->bt_adapter) {
> + rsi_bt_ops.detach(adapter->priv->bt_adapter);
> + adapter->priv->bt_adapter = NULL;
> + }
> +#endif
Ifdefs are ugly, avoid them as much as possible. Would this work:
if (IS_ENABLED(CONFIG_RSI_COEX) &&
adapter->priv->coex_mode > 1 &&
adapter->priv->bt_adapter)
BTW, why do you need the ifdef anyway, isn't it enough to check for
coex_mode?
--
Kalle Valo
Hi Kalle,
On Mon, Jan 28, 2019 at 2:59 PM Kalle Valo <[email protected]> wrote:
>
> Siva Rebbagondla <[email protected]> writes:
>
> > From: Siva Rebbagondla <[email protected]>
> >
> > As we missed to detach HCI, while entering power off or hibernation,
> > an extra hci interface gets created whenever system is woken up, to
> > avoid this we added hci_detach() in rsi_disconnect(), rsi_freeze(),
> > and rsi_shutdown() functions which are invoked for these tests.
> > This patch fixes the issue
> >
> > Signed-off-by: Siva Rebbagondla <[email protected]>
> > ---
> > drivers/net/wireless/rsi/rsi_91x_sdio.c | 21 +++++++++++++++++++--
> > drivers/net/wireless/rsi/rsi_91x_usb.c | 6 ++++++
> > 2 files changed, 25 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
> > index b412b65e..59ff778 100644
> > --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
> > +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
> > @@ -1131,7 +1131,12 @@ static void rsi_disconnect(struct sdio_func *pfunction)
> >
> > rsi_mac80211_detach(adapter);
> > mdelay(10);
> > -
> > +#ifdef CONFIG_RSI_COEX
> > + if (adapter->priv->coex_mode > 1 && adapter->priv->bt_adapter) {
> > + rsi_bt_ops.detach(adapter->priv->bt_adapter);
> > + adapter->priv->bt_adapter = NULL;
> > + }
> > +#endif
>
> Ifdefs are ugly, avoid them as much as possible. Would this work:
>
> if (IS_ENABLED(CONFIG_RSI_COEX) &&
> adapter->priv->coex_mode > 1 &&
> adapter->priv->bt_adapter)
>
> BTW, why do you need the ifdef anyway, isn't it enough to check for
> coex_mode?
Agreed. It's enough to check coex_mode with above if condition. I will
make the changes and will submit v2.
Thanks,
Siva Rebbagondla
>
>
> --
> Kalle Valo