wireless/bcm43xxx: set listen interval on lowpower
set listen interval dtim(Delivery Traffic Indication Message) on lowpower mode Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
881902d2cd
commit
5048be1bfe
drivers/wireless/ieee80211/bcm43xxx
@ -146,12 +146,24 @@ config IEEE80211_BROADCOM_DEFAULT_COUNTRY
|
||||
|
||||
if IEEE80211_BROADCOM_LOWPOWER
|
||||
|
||||
config IEEE80211_BROADCOM_LOWPOWER_TIMEOUT
|
||||
config IEEE80211_BROADCOM_LP_DTIM_TIMEOUT
|
||||
int "Broadcom BCMF lower power timeout(second)"
|
||||
default 10
|
||||
---help---
|
||||
This parameter should be enable the bcmf lower power timeout
|
||||
|
||||
config IEEE80211_BROADCOM_LP_DTIM_INTERVAL
|
||||
int "Broadcom BCMF listen interval dtim(millisecond)"
|
||||
default 500
|
||||
---help---
|
||||
This parameter should be set the listen interval dtim in milliseconds
|
||||
|
||||
config IEEE80211_BROADCOM_LP_IFDOWN_TIMEOUT
|
||||
int "Broadcom BCMF lower power if down timeout(second)"
|
||||
default 600
|
||||
---help---
|
||||
This parameter should be enable the bcmf lower power if down timeout
|
||||
|
||||
endif # IEEE80211_BROADCOM_LOWPOWER
|
||||
|
||||
if IEEE80211_BROADCOM_FULLMAC
|
||||
|
@ -426,34 +426,6 @@ 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;
|
||||
@ -492,7 +464,10 @@ int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active)
|
||||
|
||||
/* Set default power save mode */
|
||||
|
||||
ret = bcmf_wl_set_pm(priv, PM_OFF);
|
||||
out_len = 4;
|
||||
value = PM_OFF;
|
||||
ret = bcmf_cdc_ioctl(priv, interface, true, WLC_SET_PM,
|
||||
(FAR uint8_t *)&value, &out_len);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto errout_in_sdio_active;
|
||||
@ -1819,3 +1794,37 @@ int bcmf_wl_get_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
|
||||
int bcmf_wl_set_dtim(FAR struct bcmf_dev_s *priv,
|
||||
uint32_t interval_ms)
|
||||
{
|
||||
uint32_t value = interval_ms / 100;
|
||||
uint32_t out_len;
|
||||
int ret;
|
||||
|
||||
out_len = sizeof(interval_ms);
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->lp_dtim == interval_ms)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
ret = bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, true,
|
||||
IOVAR_STR_LISTEN_INTERVAL_DTIM,
|
||||
(FAR uint8_t *)&value, &out_len);
|
||||
if (ret == OK)
|
||||
{
|
||||
priv->lp_dtim = interval_ms;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -96,9 +96,10 @@ struct bcmf_dev_s
|
||||
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 */
|
||||
struct work_s lp_work_ifdown; /* Ifdown work to work queue */
|
||||
struct work_s lp_work_dtim; /* Low power work to work queue */
|
||||
int lp_dtim; /* Listen interval Delivery Traffic Indication Message */
|
||||
sclock_t lp_ticks; /* Ticks of last tx time */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -146,7 +147,9 @@ 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);
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
int bcmf_wl_set_dtim(FAR struct bcmf_dev_s *priv, uint32_t interval_ms);
|
||||
#endif
|
||||
|
||||
int bcmf_wl_set_country_code(FAR struct bcmf_dev_s *priv,
|
||||
int interface, FAR void *code);
|
||||
|
@ -88,6 +88,12 @@
|
||||
# define CONFIG_IEEE80211_BROADCOM_NINTERFACES 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
# define LP_IFDOWN_TIMEOUT CONFIG_IEEE80211_BROADCOM_LP_IFDOWN_TIMEOUT
|
||||
# define LP_DTIM_TIMEOUT CONFIG_IEEE80211_BROADCOM_LP_DTIM_TIMEOUT
|
||||
# define LP_DTIM_INTERVAL CONFIG_IEEE80211_BROADCOM_LP_DTIM_INTERVAL
|
||||
#endif
|
||||
|
||||
/* This is a helper pointer for accessing the contents of Ethernet header */
|
||||
|
||||
#define BUF ((FAR struct eth_hdr_s *)priv->bc_dev.d_buf)
|
||||
@ -762,9 +768,14 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
|
||||
priv->bc_bifup = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
if (!work_available(&priv->lp_work))
|
||||
if (!work_available(&priv->lp_work_dtim))
|
||||
{
|
||||
work_cancel(LPWORK, &priv->lp_work);
|
||||
work_cancel(LPWORK, &priv->lp_work_dtim);
|
||||
}
|
||||
|
||||
if (!work_available(&priv->lp_work_ifdown))
|
||||
{
|
||||
work_cancel(LPWORK, &priv->lp_work_ifdown);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -789,32 +800,56 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
|
||||
static void bcmf_lowpower_work(FAR void *arg)
|
||||
static bool bcmf_lowpower_expiration(FAR struct bcmf_dev_s *priv,
|
||||
FAR struct work_s *work,
|
||||
worker_t worker, clock_t timeout)
|
||||
{
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
work_queue(LPWORK, &priv->lp_work, bcmf_lowpower_work,
|
||||
priv, timeout - ticks);
|
||||
leave_critical_section(flags);
|
||||
work_queue(LPWORK, work, worker, priv, timeout - ticks);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bcmf_lowpower_work(FAR void *arg)
|
||||
{
|
||||
FAR struct bcmf_dev_s *priv = arg;
|
||||
|
||||
if (bcmf_lowpower_expiration(arg, &priv->lp_work_dtim, bcmf_lowpower_work,
|
||||
SEC2TICK(LP_DTIM_TIMEOUT)))
|
||||
{
|
||||
if (priv->bc_bifup)
|
||||
{
|
||||
bcmf_wl_set_dtim(priv, LP_DTIM_INTERVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bcmf_lowpower_ifdown_work(FAR void *arg)
|
||||
{
|
||||
FAR struct bcmf_dev_s *priv = arg;
|
||||
|
||||
if (bcmf_lowpower_expiration(arg, &priv->lp_work_ifdown,
|
||||
bcmf_lowpower_ifdown_work,
|
||||
SEC2TICK(LP_IFDOWN_TIMEOUT)))
|
||||
{
|
||||
if (priv->bc_bifup)
|
||||
{
|
||||
netdev_ifdown(&priv->bc_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -832,24 +867,26 @@ static void bcmf_lowpower_work(FAR void *arg)
|
||||
|
||||
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);
|
||||
bcmf_wl_set_dtim(priv, 100); /* Listen-iterval to 100 ms */
|
||||
|
||||
/* 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)
|
||||
if (work_available(&priv->lp_work_dtim) &&
|
||||
priv->lp_dtim != LP_DTIM_INTERVAL)
|
||||
{
|
||||
work_queue(LPWORK, &priv->lp_work, bcmf_lowpower_work, priv,
|
||||
SEC2TICK(CONFIG_IEEE80211_BROADCOM_LOWPOWER_TIMEOUT));
|
||||
work_queue(LPWORK, &priv->lp_work_dtim, bcmf_lowpower_work, priv,
|
||||
SEC2TICK(LP_DTIM_TIMEOUT));
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
if (work_available(&priv->lp_work_ifdown))
|
||||
{
|
||||
work_queue(LPWORK, &priv->lp_work_ifdown,
|
||||
bcmf_lowpower_ifdown_work, priv,
|
||||
SEC2TICK(LP_IFDOWN_TIMEOUT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user