wireless/bcm43xxx: add Packet Traffic Arbitration Priority support
For Bluetooth wifi co-existence Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
8f5a6930e8
commit
ff2b87c298
@ -156,6 +156,12 @@ config IEEE80211_BROADCOM_SCAN_RESULT_ENTRIES
|
|||||||
---help---
|
---help---
|
||||||
This parameter should be set the bcmf escan result buffer entries
|
This parameter should be set the bcmf escan result buffer entries
|
||||||
|
|
||||||
|
config IEEE80211_BROADCOM_PTA_PRIORITY
|
||||||
|
bool "Broadcom BCMF Packet Traffic Arbitration priority"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
This parameter should be enable the bcmf PTA priority feature
|
||||||
|
|
||||||
config IEEE80211_BROADCOM_LOWPOWER
|
config IEEE80211_BROADCOM_LOWPOWER
|
||||||
bool "Broadcom BCMF lower power"
|
bool "Broadcom BCMF lower power"
|
||||||
depends on IEEE80211_BROADCOM_FULLMAC
|
depends on IEEE80211_BROADCOM_FULLMAC
|
||||||
|
@ -419,6 +419,34 @@ int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
|
|||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_IEEE80211_BROADCOM_HAVE_CLM */
|
#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 = OK;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: bcmf_wl_active
|
* Name: bcmf_wl_active
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -1714,13 +1742,23 @@ int bcmf_wl_get_bssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
|||||||
* Get the channel for the device
|
* Get the channel for the device
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, int interface)
|
||||||
{
|
{
|
||||||
channel_info_t ci;
|
channel_info_t ci;
|
||||||
uint32_t out_len;
|
uint32_t out_len;
|
||||||
int interface;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
out_len = sizeof(ci);
|
||||||
|
ret = bcmf_cdc_ioctl(priv, interface, false,
|
||||||
|
WLC_GET_CHANNEL, (uint8_t *)&ci, &out_len);
|
||||||
|
return ret == OK ? ci.target_channel : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcmf_wl_get_frequency(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
||||||
|
{
|
||||||
|
int interface;
|
||||||
|
int channel;
|
||||||
|
|
||||||
interface = bcmf_wl_get_interface(priv, iwr);
|
interface = bcmf_wl_get_interface(priv, iwr);
|
||||||
|
|
||||||
if (interface < 0)
|
if (interface < 0)
|
||||||
@ -1728,15 +1766,15 @@ int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_len = sizeof(ci);
|
channel = bcmf_wl_get_channel(priv, interface);
|
||||||
ret = bcmf_cdc_ioctl(priv, interface, false,
|
if (channel < 0)
|
||||||
WLC_GET_CHANNEL, (FAR uint8_t *)&ci, &out_len);
|
|
||||||
if (ret == OK)
|
|
||||||
{
|
{
|
||||||
iwr->u.freq.m = bcmf_wl_channel_to_frequency(ci.target_channel);
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
iwr->u.freq.m = bcmf_wl_channel_to_frequency(channel);
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1827,10 +1865,8 @@ int bcmf_wl_get_txpower(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_get_iwrange(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
||||||
{
|
{
|
||||||
struct iw_range *range;
|
struct iw_range *range;
|
||||||
channel_info_t ci;
|
|
||||||
uint32_t out_len;
|
|
||||||
int interface;
|
int interface;
|
||||||
int ret;
|
int channel;
|
||||||
|
|
||||||
interface = bcmf_wl_get_interface(priv, iwr);
|
interface = bcmf_wl_get_interface(priv, iwr);
|
||||||
|
|
||||||
@ -1848,16 +1884,16 @@ int bcmf_wl_get_iwrange(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
|||||||
|
|
||||||
memset(range, 0, sizeof(*range));
|
memset(range, 0, sizeof(*range));
|
||||||
|
|
||||||
out_len = sizeof(ci);
|
channel = bcmf_wl_get_channel(priv, interface);
|
||||||
ret = bcmf_cdc_ioctl(priv, interface, false,
|
if (channel < 0)
|
||||||
WLC_GET_CHANNEL, (FAR uint8_t *)&ci, &out_len);
|
|
||||||
if (ret == OK)
|
|
||||||
{
|
{
|
||||||
range->num_frequency = 1;
|
return channel;
|
||||||
range->freq[0].m = bcmf_wl_channel_to_frequency(ci.target_channel);
|
|
||||||
range->freq[0].i = ci.target_channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
range->num_frequency = 1;
|
||||||
|
range->freq[0].m = bcmf_wl_channel_to_frequency(channel);
|
||||||
|
range->freq[0].i = channel;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2193,3 +2229,61 @@ int bcmf_wl_set_dtim(FAR struct bcmf_dev_s *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211_BROADCOM_PTA_PRIORITY
|
||||||
|
|
||||||
|
int bcmf_wl_get_pta(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
||||||
|
{
|
||||||
|
iwr->u.param.value = priv->pta_priority;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcmf_wl_set_pta_priority(FAR struct bcmf_dev_s *priv, uint32_t prio)
|
||||||
|
{
|
||||||
|
uint32_t out_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
wl_pta_t pta_prio_map[IW_PTA_PRIORITY_WLAN_MAXIMIZED + 1] =
|
||||||
|
{
|
||||||
|
{ 0, 50, },
|
||||||
|
{ 10, 50, },
|
||||||
|
{ 25, 50, },
|
||||||
|
{ 40, 50, },
|
||||||
|
{ 50, 50, },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (prio > IW_PTA_PRIORITY_WLAN_MAXIMIZED)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->pta_priority == prio)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
out_len = sizeof(wl_pta_t);
|
||||||
|
ret = bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, true,
|
||||||
|
IOVAR_STR_COEX_PARA,
|
||||||
|
(uint8_t *)&pta_prio_map[prio],
|
||||||
|
&out_len);
|
||||||
|
if (ret == OK)
|
||||||
|
{
|
||||||
|
priv->pta_priority = prio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcmf_wl_set_pta(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
||||||
|
{
|
||||||
|
if (bcmf_wl_get_interface(priv, iwr) < 0)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bcmf_wl_set_pta_priority(priv, iwr->u.param.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -103,6 +103,9 @@ struct bcmf_dev_s
|
|||||||
int lp_dtim; /* Listen interval Delivery Traffic Indication Message */
|
int lp_dtim; /* Listen interval Delivery Traffic Indication Message */
|
||||||
sclock_t lp_ticks; /* Ticks of last tx time */
|
sclock_t lp_ticks; /* Ticks of last tx time */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_IEEE80211_BROADCOM_PTA_PRIORITY
|
||||||
|
int pta_priority; /* Current priority of Packet Traffic Arbitration */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Default bus interface structure */
|
/* Default bus interface structure */
|
||||||
@ -187,7 +190,7 @@ int bcmf_wl_get_ssid(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
|||||||
int bcmf_wl_set_bssid(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
int bcmf_wl_set_bssid(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
||||||
int bcmf_wl_get_bssid(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
int bcmf_wl_get_bssid(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
||||||
|
|
||||||
int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
int bcmf_wl_get_frequency(FAR struct bcmf_dev_s *priv, struct iwreq *iwr);
|
||||||
|
|
||||||
int bcmf_wl_get_rate(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
int bcmf_wl_get_rate(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
||||||
|
|
||||||
@ -200,4 +203,17 @@ int bcmf_wl_get_iwrange(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
|||||||
int bcmf_wl_set_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
int bcmf_wl_set_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
||||||
int bcmf_wl_get_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
int bcmf_wl_get_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr);
|
||||||
|
|
||||||
|
int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, int interface);
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211_BROADCOM_PTA_PRIORITY
|
||||||
|
int bcmf_wl_get_pta(FAR struct bcmf_dev_s *priv, struct iwreq *iwr);
|
||||||
|
int bcmf_wl_set_pta(FAR struct bcmf_dev_s *priv, struct iwreq *iwr);
|
||||||
|
|
||||||
|
int bcmf_wl_set_pta_priority(FAR struct bcmf_dev_s *priv, uint32_t prio);
|
||||||
|
#else
|
||||||
|
# define bcmf_wl_get_pta(...)
|
||||||
|
# define bcmf_wl_set_pta(...)
|
||||||
|
# define bcmf_wl_set_pta_priority(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_DRIVER_H */
|
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_DRIVER_H */
|
||||||
|
@ -873,6 +873,7 @@ end_packed_struct wlc_iov_trx_t;
|
|||||||
#define IOVAR_STR_CCGPIOIN "ccgpioin"
|
#define IOVAR_STR_CCGPIOIN "ccgpioin"
|
||||||
#define IOVAR_STR_CCGPIOOUT "ccgpioout"
|
#define IOVAR_STR_CCGPIOOUT "ccgpioout"
|
||||||
#define IOVAR_STR_CCGPIOPUTEN "ccgpioputen"
|
#define IOVAR_STR_CCGPIOPUTEN "ccgpioputen"
|
||||||
|
#define IOVAR_STR_COEX_PARA "coex_para"
|
||||||
|
|
||||||
#define WLC_IOCTL_MAGIC ( 0x14e46c77 )
|
#define WLC_IOCTL_MAGIC ( 0x14e46c77 )
|
||||||
#define WLC_IOCTL_VERSION ( 1 )
|
#define WLC_IOCTL_VERSION ( 1 )
|
||||||
@ -3025,6 +3026,14 @@ end_packed_struct;
|
|||||||
|
|
||||||
typedef struct edcf_acparam edcf_acparam_t;
|
typedef struct edcf_acparam edcf_acparam_t;
|
||||||
|
|
||||||
|
/* Packet Traffic Arbitration */
|
||||||
|
|
||||||
|
typedef struct wl_pta
|
||||||
|
{
|
||||||
|
uint16_t radio;
|
||||||
|
uint16_t duration;
|
||||||
|
} wl_pta_t;
|
||||||
|
|
||||||
/* Stop packing structures */
|
/* Stop packing structures */
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
@ -652,6 +652,8 @@ static int bcmf_ifup(FAR struct net_driver_s *dev)
|
|||||||
bcmf_lowpower_poll(priv);
|
bcmf_lowpower_poll(priv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_COEX_HIGH);
|
||||||
|
|
||||||
goto errout_in_critical_section;
|
goto errout_in_critical_section;
|
||||||
|
|
||||||
errout_in_wl_active:
|
errout_in_wl_active:
|
||||||
@ -708,6 +710,8 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_COEX_MAXIMIZED);
|
||||||
|
|
||||||
bcmf_wl_enable(priv, false);
|
bcmf_wl_enable(priv, false);
|
||||||
bcmf_wl_active(priv, false);
|
bcmf_wl_active(priv, false);
|
||||||
}
|
}
|
||||||
@ -1022,11 +1026,24 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
|||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case SIOCSIWSCAN:
|
case SIOCSIWSCAN:
|
||||||
|
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_WLAN_MAXIMIZED);
|
||||||
ret = bcmf_wl_start_scan(priv, (struct iwreq *)arg);
|
ret = bcmf_wl_start_scan(priv, (struct iwreq *)arg);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
bcmf_wl_set_pta_priority(priv, IFF_IS_RUNNING(dev->d_flags) ?
|
||||||
|
IW_PTA_PRIORITY_BALANCED :
|
||||||
|
IW_PTA_PRIORITY_COEX_HIGH);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCGIWSCAN:
|
case SIOCGIWSCAN:
|
||||||
ret = bcmf_wl_get_scan_results(priv, (struct iwreq *)arg);
|
ret = bcmf_wl_get_scan_results(priv, (struct iwreq *)arg);
|
||||||
|
if (ret != -EAGAIN)
|
||||||
|
{
|
||||||
|
bcmf_wl_set_pta_priority(priv, IFF_IS_RUNNING(dev->d_flags) ?
|
||||||
|
IW_PTA_PRIORITY_BALANCED :
|
||||||
|
IW_PTA_PRIORITY_COEX_HIGH);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCSIFHWADDR: /* Set device MAC address */
|
case SIOCSIFHWADDR: /* Set device MAC address */
|
||||||
@ -1047,7 +1064,7 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCGIWFREQ: /* Get channel/frequency (Hz) */
|
case SIOCGIWFREQ: /* Get channel/frequency (Hz) */
|
||||||
ret = bcmf_wl_get_channel(priv, (struct iwreq *)arg);
|
ret = bcmf_wl_get_frequency(priv, (struct iwreq *)arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCSIWMODE: /* Set operation mode */
|
case SIOCSIWMODE: /* Set operation mode */
|
||||||
@ -1067,7 +1084,19 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCSIWESSID: /* Set ESSID (network name) */
|
case SIOCSIWESSID: /* Set ESSID (network name) */
|
||||||
|
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_WLAN_MAXIMIZED);
|
||||||
ret = bcmf_wl_set_ssid(priv, (struct iwreq *)arg);
|
ret = bcmf_wl_set_ssid(priv, (struct iwreq *)arg);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_COEX_HIGH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bcmf_wl_set_pta_priority(priv, (bcmf_wl_get_channel(priv,
|
||||||
|
CHIP_STA_INTERFACE) > 14) ?
|
||||||
|
IW_PTA_PRIORITY_COEX_MAXIMIZED :
|
||||||
|
IW_PTA_PRIORITY_BALANCED);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCGIWESSID: /* Get ESSID */
|
case SIOCGIWESSID: /* Get ESSID */
|
||||||
@ -1108,6 +1137,16 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
|||||||
ret = bcmf_wl_get_country(priv, (struct iwreq *)arg);
|
ret = bcmf_wl_get_country(priv, (struct iwreq *)arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211_BROADCOM_PTA_PRIORITY
|
||||||
|
case SIOCGIWPTAPRIO: /* Get Packet Traffic Arbitration */
|
||||||
|
ret = bcmf_wl_get_pta(priv, (struct iwreq *)arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIOCSIWPTAPRIO: /* Set Packet Traffic Arbitration */
|
||||||
|
ret = bcmf_wl_set_pta(priv, (struct iwreq *)arg);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
nerr("ERROR: Unrecognized IOCTL command: %x\n", cmd);
|
nerr("ERROR: Unrecognized IOCTL command: %x\n", cmd);
|
||||||
ret = -ENOTTY; /* Special return value for this case */
|
ret = -ENOTTY; /* Special return value for this case */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user