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---
|
||||
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
|
||||
bool "Broadcom BCMF lower power"
|
||||
depends on IEEE80211_BROADCOM_FULLMAC
|
||||
|
@ -419,6 +419,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 = 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
|
||||
****************************************************************************/
|
||||
@ -1714,13 +1742,23 @@ int bcmf_wl_get_bssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
||||
* 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;
|
||||
uint32_t out_len;
|
||||
int interface;
|
||||
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);
|
||||
|
||||
if (interface < 0)
|
||||
@ -1728,15 +1766,15 @@ int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
out_len = sizeof(ci);
|
||||
ret = bcmf_cdc_ioctl(priv, interface, false,
|
||||
WLC_GET_CHANNEL, (FAR uint8_t *)&ci, &out_len);
|
||||
if (ret == OK)
|
||||
channel = bcmf_wl_get_channel(priv, interface);
|
||||
if (channel < 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
struct iw_range *range;
|
||||
channel_info_t ci;
|
||||
uint32_t out_len;
|
||||
int interface;
|
||||
int ret;
|
||||
int channel;
|
||||
|
||||
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));
|
||||
|
||||
out_len = sizeof(ci);
|
||||
ret = bcmf_cdc_ioctl(priv, interface, false,
|
||||
WLC_GET_CHANNEL, (FAR uint8_t *)&ci, &out_len);
|
||||
if (ret == OK)
|
||||
channel = bcmf_wl_get_channel(priv, interface);
|
||||
if (channel < 0)
|
||||
{
|
||||
range->num_frequency = 1;
|
||||
range->freq[0].m = bcmf_wl_channel_to_frequency(ci.target_channel);
|
||||
range->freq[0].i = ci.target_channel;
|
||||
return channel;
|
||||
}
|
||||
|
||||
range->num_frequency = 1;
|
||||
range->freq[0].m = bcmf_wl_channel_to_frequency(channel);
|
||||
range->freq[0].i = channel;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -2193,3 +2229,61 @@ int bcmf_wl_set_dtim(FAR struct bcmf_dev_s *priv,
|
||||
}
|
||||
|
||||
#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 */
|
||||
sclock_t lp_ticks; /* Ticks of last tx time */
|
||||
#endif
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_PTA_PRIORITY
|
||||
int pta_priority; /* Current priority of Packet Traffic Arbitration */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* 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_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);
|
||||
|
||||
@ -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_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 */
|
||||
|
@ -873,6 +873,7 @@ end_packed_struct wlc_iov_trx_t;
|
||||
#define IOVAR_STR_CCGPIOIN "ccgpioin"
|
||||
#define IOVAR_STR_CCGPIOOUT "ccgpioout"
|
||||
#define IOVAR_STR_CCGPIOPUTEN "ccgpioputen"
|
||||
#define IOVAR_STR_COEX_PARA "coex_para"
|
||||
|
||||
#define WLC_IOCTL_MAGIC ( 0x14e46c77 )
|
||||
#define WLC_IOCTL_VERSION ( 1 )
|
||||
@ -3025,6 +3026,14 @@ end_packed_struct;
|
||||
|
||||
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 */
|
||||
|
||||
#pragma pack()
|
||||
|
@ -652,6 +652,8 @@ static int bcmf_ifup(FAR struct net_driver_s *dev)
|
||||
bcmf_lowpower_poll(priv);
|
||||
#endif
|
||||
|
||||
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_COEX_HIGH);
|
||||
|
||||
goto errout_in_critical_section;
|
||||
|
||||
errout_in_wl_active:
|
||||
@ -708,6 +710,8 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_COEX_MAXIMIZED);
|
||||
|
||||
bcmf_wl_enable(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)
|
||||
{
|
||||
case SIOCSIWSCAN:
|
||||
bcmf_wl_set_pta_priority(priv, IW_PTA_PRIORITY_WLAN_MAXIMIZED);
|
||||
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;
|
||||
|
||||
case SIOCGIWSCAN:
|
||||
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;
|
||||
|
||||
case SIOCSIFHWADDR: /* Set device MAC address */
|
||||
@ -1047,7 +1064,7 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case SIOCSIWMODE: /* Set operation mode */
|
||||
@ -1067,7 +1084,19 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
break;
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
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);
|
||||
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:
|
||||
nerr("ERROR: Unrecognized IOCTL command: %x\n", cmd);
|
||||
ret = -ENOTTY; /* Special return value for this case */
|
||||
|
Loading…
x
Reference in New Issue
Block a user