Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions boards/shields/nxp_m2_wifi_bt/nxp_m2_2ll_wifi_bt.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
&m2_wifi_sdio {
nxp_wifi {
compatible = "nxp,wifi";
wakeup-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
status = "okay";
};
};
4 changes: 2 additions & 2 deletions drivers/wifi/nxp/Kconfig.nxp
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ menu "Wi-Fi driver Stack configurations"

config NXP_WIFI_MON_TASK_STACK_SIZE
int "Mon thread stack size"
depends on NXP_RW610
depends on NXP_RW610 || NXP_IW610
default 3072
help
This option specifies the size of the stack used by the mon task.
Expand Down Expand Up @@ -444,7 +444,7 @@ menu "Wi-Fi thread priority configurations"

config NXP_WIFI_MON_TASK_PRIO
int "Mon task priority"
depends on NXP_RW610
depends on NXP_RW610 || NXP_IW610
default 4
help
This option specifies the priority of the mon task.
Expand Down
78 changes: 73 additions & 5 deletions drivers/wifi/nxp/nxp_wifi_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <zephyr/net/wifi_mgmt.h>
#ifdef CONFIG_PM_DEVICE
#include <zephyr/pm/device.h>
#ifdef CONFIG_NXP_IW610
#include <fsl_gpc.h>
#endif
#endif
#ifdef CONFIG_WIFI_NM
#include <zephyr/net/wifi_nm.h>
Expand Down Expand Up @@ -73,7 +76,7 @@ extern struct interface g_uap;
extern const rtos_wpa_supp_dev_ops wpa_supp_ops;
#endif

#if defined(CONFIG_PM_DEVICE) && defined(CONFIG_NXP_RW610)
#ifdef CONFIG_PM_DEVICE
extern int is_hs_handshake_done;
extern int wlan_host_sleep_state;
extern bool skip_hs_handshake;
Expand Down Expand Up @@ -2014,6 +2017,18 @@ extern void WL_MCI_WAKEUP0_DriverIRQHandler(void);
extern void WL_MCI_WAKEUP_DONE0_DriverIRQHandler(void);
#endif

#ifdef CONFIG_PM_DEVICE
#ifdef CONFIG_NXP_IW610
struct gpio_callback wakeup_callback;

static void gpio_wakeup_callback(const struct device *port, struct gpio_callback *cb,
gpio_port_pins_t pins)
{
/* TODO: Reserved for future use. */
}
#endif
#endif

static int nxp_wifi_dev_init(const struct device *dev)
{
struct nxp_wifi_dev *nxp_wifi = &nxp_wifi0;
Expand All @@ -2028,8 +2043,46 @@ static int nxp_wifi_dev_init(const struct device *dev)
#if (DT_INST_PROP(0, wakeup_source))
NXP_ENABLE_WAKEUP_SIGNAL(IMU_IRQ_N);
#endif /* DT_INST_PROP */
#endif /* CONFIG_NXP_RW610 */
#elif defined(CONFIG_NXP_IW610)
#ifdef CONFIG_PM_DEVICE
#if DT_NODE_HAS_PROP(DT_DRV_INST(0), wakeup_gpios)
int err = 0;
struct gpio_dt_spec wakeup = GPIO_DT_SPEC_GET(DT_DRV_INST(0), wakeup_gpios);

if (!gpio_is_ready_dt(&wakeup)) {
LOG_ERR("Error: failed to configure wakeup %s pin %d", wakeup.port->name,
wakeup.pin);
return -EIO;
}

/* Configure wakeup gpio as input */
err = gpio_pin_configure_dt(&wakeup, GPIO_INPUT);
if (err) {
LOG_ERR("Error %d: failed to configure wakeup %s pin %d", err,
wakeup.port->name, wakeup.pin);
return err;
}

err = gpio_pin_set_dt(&wakeup, 0);
if (err) {
return err;
}

/* Configure wakeup gpio interrupt */
err = gpio_pin_interrupt_configure_dt(&wakeup, GPIO_INT_EDGE_FALLING);
if (err) {
return err;
}

/* Set wakeup gpio callback function */
gpio_init_callback(&wakeup_callback, gpio_wakeup_callback, BIT(wakeup.pin));
err = gpio_add_callback_dt(&wakeup, &wakeup_callback);
if (err) {
return err;
}
#endif
#endif
#endif
return 0;
}

Expand Down Expand Up @@ -2068,7 +2121,8 @@ static int nxp_wifi_set_config(const struct device *dev, enum ethernet_config_ty
return 0;
}

#if defined(CONFIG_PM_DEVICE) && defined(CONFIG_NXP_RW610)
#ifdef CONFIG_PM_DEVICE
#ifdef CONFIG_NXP_RW610
void device_pm_dump_wakeup_source(void)
{
if (POWER_GetWakeupStatus(IMU_IRQ_N)) {
Expand All @@ -2082,6 +2136,18 @@ void device_pm_dump_wakeup_source(void)
POWER_ClearWakeupStatus(32);
}
}
#endif

static bool nxp_wifi_wlan_wakeup(void)
{
#ifdef CONFIG_NXP_RW610
return POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn);
#elif CONFIG_NXP_IW610
return GPC_GetIRQStatusFlag(GPC, GPIO1_Combined_0_15_IRQn);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type of wakeup code should be in the GPIO driver and not in the driver. The driver should only have to use the GPIO_INT_WAKEUP flag in the device tree node.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For IW610, we use OOB wakeup as WLAN wakeup method. This means if firmware received WLAN packet that matches wakeup condition, firmware will toggle the specific GPIO0_1. This GPIO pin is on M2 port (IW610 will be attached here) of EVKC1060 and is used for WLAN specifically. I think it is a proper way to add it in WLAN driver.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, where are you configuring the GPIO interrupt to be wakeup capable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consulted someone from EP team about this and he told me that all interrupts were enabled as wakeup sources by default. Checked value of GPC->IMR1 ~ GPC->IMR5 registers and confirmed. This was also confirmed during tests.
Therefore, no additional action needed for GPIO wakeup capable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at this PR: #95813
This should allow removing the platform specific #defines from this driver.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed your PR and noticed that you added new macro define NXP_GET_WAKEUP_SIGNAL_STATUS(irqn) in all NXP socs. But the IRQ number is different for different platform, I think the platform specific defines are still needed.
Maybe it could be like this:

#ifdef CONFIG_NXP_RW610
#define WAKEUP_IRQ WL_MCI_WAKEUP0_IRQn
#elif CONFIG_NXP_IW610
#define WAKEUP_IRQ GPIO1_Combined_0_15_IRQn
#else
#define WAKEUP_IRQ 0
#endif
...
static bool nxp_wifi_wlan_wakeup(void)
{
    return NXP_GET_WAKEUP_SIGNAL_STATUS(WAKEUP_IRQ);
}

Please add your comment. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get the Wakeup IRQ from Device Tree. You could use interrupt-names to name the interrupts and use DT_IRQ_BY_NAME and DT_IRQ_HAS_NAME to get the wakeup interrupt.
For the one's that needs GPIO, this can be set at the board-level dts file.

#else
return false;
#endif
}

static int device_wlan_pm_action(const struct device *dev, enum pm_device_action pm_action)
{
Expand Down Expand Up @@ -2126,17 +2192,19 @@ static int device_wlan_pm_action(const struct device *dev, enum pm_device_action
/* If we are not woken up by WLAN, skip posting host sleep exit event.
* And skip host sleep handshake next time we are about to sleep.
*/
if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn)) {
if (nxp_wifi_wlan_wakeup()) {
ret = wlan_hs_send_event(HOST_SLEEP_EXIT, NULL);
if (ret != 0) {
return -EFAULT;
}
wlan_hs_hanshake_cfg(false);
} else {
LOG_INF("Wakeup by other sources");
wlan_hs_hanshake_cfg(true);
}

#ifdef CONFIG_NXP_RW610
device_pm_dump_wakeup_source();
#endif
if (wlan_host_sleep_state == HOST_SLEEP_ONESHOT) {
wlan_host_sleep_state = HOST_SLEEP_DISABLE;
wlan_hs_hanshake_cfg(false);
Expand Down
9 changes: 9 additions & 0 deletions dts/bindings/wifi/nxp,wifi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ description: |
compatible: "nxp,wifi"

include: [base.yaml, pinctrl-device.yaml]

properties:
wakeup-gpios:
type: phandle-array
description: |
WLAN wakeup host pin
This pin defaults to active low when consumed by the SDK card. The
property value should ensure the flags properly describ the signal
that is presendted to the driver.
6 changes: 6 additions & 0 deletions samples/net/wifi/shell/nxp/overlay_iw610.conf
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@ CONFIG_ETH_DRIVER=n
CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO=y
CONFIG_NET_MGMT_THREAD_PRIORITY=3
CONFIG_NXP_WIFI_DRIVER_TASK_PRIO=2

# power mgmt
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_LOG_LEVEL_OFF=y
CONFIG_PM_DEVICE_LOG_LEVEL_OFF=y
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ manifest:
groups:
- hal
- name: hal_nxp
revision: 54f8ccc592f499f63fedc39485be363df8a90c35
revision: 870b2a59e85355616e7ddc52421d86f374d5486c
path: modules/hal/nxp
groups:
- hal
Expand Down