Skip to content

Commit 9fcb697

Browse files
committed
Ignore power down event with disable_powersave=1 module option
When the chip is in lower power state, it listens only for the packets which destination MAC match device's MAC address. Incoming broadcast and multicast packets, which MAC does not equal to the device MAC, gets dropped. This breaks mDNS and other protocols. Power saving works as follows: the chip sends PWR_DOWN event to the kernel module when it's ready to go into lower state, and if the kernel is also ready (nothing in tx queue), it replies with ACK. Add disable_powersave=1 kernel option to ignore PWR_DOWN event completely to reliably accept multicast, at the cost of +0.4W Link: orangepi-xunlong/linux-orangepi#98 (comment)
1 parent d6bec75 commit 9fcb697

3 files changed

Lines changed: 11 additions & 0 deletions

File tree

unisocwifi/cmdevt.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3257,6 +3257,12 @@ static void sprdwl_event_fw_power_down(struct sprdwl_vif *vif, u8 *data, u16 len
32573257
{
32583258
struct sprdwl_work *misc_work;
32593259

3260+
/* When powersave is disabled, silently ignore the firmware's sleep
3261+
* request. Responding with value=0 causes the firmware to immediately
3262+
* re-send WIFI_EVENT_FW_PWR_DOWN in a tight loop, burning CPU. */
3263+
if (disable_powersave)
3264+
return;
3265+
32603266
misc_work = sprdwl_alloc_work(0);
32613267
if (!misc_work) {
32623268
wl_err("%s out of memory\n", __func__);

unisocwifi/cmdevt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#define SPRDWL_11V_ALL_FEATURE 0xFFFF
7676

7777
extern unsigned int wfa_cap;
78+
extern unsigned int disable_powersave;
7879
enum SPRDWL_CMD_LIST {
7980
WIFI_CMD_MIN = 0,
8081
WIFI_CMD_ERR = WIFI_CMD_MIN,

unisocwifi/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,10 @@ unsigned int wfa_cap;
16581658
module_param(wfa_cap, uint, 0000);
16591659
MODULE_PARM_DESC(wfa_cap, "set capability for WFA test");
16601660

1661+
unsigned int disable_powersave;
1662+
module_param(disable_powersave, uint, 0000);
1663+
MODULE_PARM_DESC(disable_powersave, "Disable firmware power save mode (0=default, 1=ignore EVENT_PWR_DOWN)");
1664+
16611665
unsigned int tcp_ack_drop_cnt = SPRDWL_TCP_ACK_DROP_CNT;
16621666
/* Maybe you need S_IRUGO | S_IWUSR for debug */
16631667
module_param(tcp_ack_drop_cnt, uint, 0000);

0 commit comments

Comments
 (0)