wireless/bcm43xxx: add auto power saving support
switch firmware power mode between PM_MAX/PM_FAST Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
0fe219a8c9
commit
04fcbb5cb8
@ -132,6 +132,22 @@ config IEEE80211_BROADCOM_SCAN_RESULT_ENTRIES
|
||||
---help---
|
||||
This parameter should be set the bcmf escan result buffer entries
|
||||
|
||||
config IEEE80211_BROADCOM_LOWPOWER
|
||||
bool "Broadcom BCMF lower power"
|
||||
default n
|
||||
---help---
|
||||
This parameter should be enable the bcmf lower power mode
|
||||
|
||||
if IEEE80211_BROADCOM_LOWPOWER
|
||||
|
||||
config IEEE80211_BROADCOM_LOWPOWER_TIMEOUT
|
||||
int "Broadcom BCMF lower power timeout(second)"
|
||||
default 10
|
||||
---help---
|
||||
This parameter should be enable the bcmf lower power timeout
|
||||
|
||||
endif # IEEE80211_BROADCOM_LOWPOWER
|
||||
|
||||
if IEEE80211_BROADCOM_FULLMAC
|
||||
|
||||
config IEEE80211_BROADCOM_NINTERFACES
|
||||
|
@ -426,6 +426,34 @@ int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211_BROADCOM_HAVE_CLM */
|
||||
|
||||
int bcmf_wl_set_pm(FAR struct bcmf_dev_s *priv, int mode)
|
||||
{
|
||||
int interface = CHIP_STA_INTERFACE;
|
||||
uint32_t out_len;
|
||||
uint32_t value;
|
||||
int ret;
|
||||
|
||||
/* Set default power save mode */
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
if (priv->lp_mode != mode)
|
||||
#endif
|
||||
{
|
||||
out_len = 4;
|
||||
value = mode;
|
||||
ret = bcmf_cdc_ioctl(priv, interface, true, WLC_SET_PM,
|
||||
(uint8_t *)&value, &out_len);
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
if (ret == OK)
|
||||
{
|
||||
priv->lp_mode = mode;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active)
|
||||
{
|
||||
int interface = CHIP_STA_INTERFACE;
|
||||
@ -462,12 +490,9 @@ int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active)
|
||||
goto errout_in_sdio_active;
|
||||
}
|
||||
|
||||
/* FIXME disable power save mode */
|
||||
/* Set default power save mode */
|
||||
|
||||
out_len = 4;
|
||||
value = 0;
|
||||
ret = bcmf_cdc_ioctl(priv, interface, true, WLC_SET_PM,
|
||||
(uint8_t *)&value, &out_len);
|
||||
ret = bcmf_wl_set_pm(priv, PM_OFF);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto errout_in_sdio_active;
|
||||
|
@ -94,6 +94,12 @@ struct bcmf_dev_s
|
||||
|
||||
sem_t auth_signal; /* Authentication notification signal */
|
||||
int auth_status; /* Authentication status */
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
struct work_s lp_work; /* Low power work to work queue */
|
||||
int lp_mode; /* Low power mode */
|
||||
sclock_t lp_ticks; /* Ticks of last tx time */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Default bus interface structure */
|
||||
@ -138,6 +144,10 @@ int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, struct ifreq *req);
|
||||
|
||||
int bcmf_wl_enable(FAR struct bcmf_dev_s *priv, bool enable);
|
||||
|
||||
int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active);
|
||||
|
||||
int bcmf_wl_set_pm(FAR struct bcmf_dev_s *priv, int mode);
|
||||
|
||||
/* IOCTLs AP scan interface implementation */
|
||||
|
||||
int bcmf_wl_start_scan(FAR struct bcmf_dev_s *priv, struct iwreq *iwr);
|
||||
@ -169,6 +179,4 @@ int bcmf_wl_get_rssi(FAR struct bcmf_dev_s *priv, struct iwreq *iwr);
|
||||
|
||||
int bcmf_wl_get_iwrange(FAR struct bcmf_dev_s *priv, struct iwreq *iwr);
|
||||
|
||||
int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active);
|
||||
|
||||
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_DRIVER_H */
|
||||
|
@ -127,6 +127,10 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
static void bcmf_lowpower_poll(FAR struct bcmf_dev_s *priv);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -703,6 +707,10 @@ static int bcmf_ifup(FAR struct net_driver_s *dev)
|
||||
|
||||
priv->bc_bifup = true;
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
bcmf_lowpower_poll(priv);
|
||||
#endif
|
||||
|
||||
goto errout_in_critical_section;
|
||||
|
||||
errout_in_wl_active:
|
||||
@ -742,6 +750,13 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
|
||||
|
||||
if (priv->bc_bifup)
|
||||
{
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
if (!work_available(&priv->lp_work))
|
||||
{
|
||||
work_cancel(LPWORK, &priv->lp_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
bcmf_wl_enable(priv, false);
|
||||
bcmf_wl_active(priv, false);
|
||||
|
||||
@ -755,6 +770,84 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcmf_lowpower_work
|
||||
*
|
||||
* Description:
|
||||
* Process low power saving dueto work timer expiration
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - context of device to use
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
static void bcmf_lowpower_work(FAR void *arg)
|
||||
{
|
||||
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)arg;
|
||||
irqstate_t flags;
|
||||
clock_t ticks;
|
||||
clock_t timeout;
|
||||
|
||||
if (priv->bc_bifup)
|
||||
{
|
||||
/* Disable the hardware interrupt */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
ticks = clock_systime_ticks() - priv->lp_ticks;
|
||||
timeout = SEC2TICK(CONFIG_IEEE80211_BROADCOM_LOWPOWER_TIMEOUT);
|
||||
|
||||
if (ticks >= timeout)
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
bcmf_wl_set_pm(priv, PM_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
work_queue(LPWORK, &priv->lp_work, bcmf_lowpower_work,
|
||||
priv, timeout - ticks);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcmf_lowpower_poll
|
||||
*
|
||||
* Description:
|
||||
* Polling low power
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - context of device to use
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcmf_lowpower_poll(FAR struct bcmf_dev_s *priv)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
if (priv->bc_bifup)
|
||||
{
|
||||
bcmf_wl_set_pm(priv, PM_FAST);
|
||||
|
||||
/* Disable the hardware interrupt */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
priv->lp_ticks = clock_systime_ticks();
|
||||
if (work_available(&priv->lp_work) && priv->lp_mode != PM_MAX)
|
||||
{
|
||||
work_queue(LPWORK, &priv->lp_work, bcmf_lowpower_work, priv,
|
||||
SEC2TICK(CONFIG_IEEE80211_BROADCOM_LOWPOWER_TIMEOUT));
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcmf_txavail
|
||||
*
|
||||
@ -778,6 +871,9 @@ static int bcmf_txavail(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
bcmf_lowpower_poll(priv);
|
||||
#endif
|
||||
bcmf_netdev_notify_tx(priv);
|
||||
return OK;
|
||||
}
|
||||
@ -944,6 +1040,10 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
bcmf_lowpower_poll(priv);
|
||||
#endif
|
||||
|
||||
/* Decode and dispatch the driver-specific IOCTL command */
|
||||
|
||||
switch (cmd)
|
||||
|
Loading…
Reference in New Issue
Block a user