qcacld-3.0: Fix a peer phy mode update discrepancy
In function wma_process_update_opmode, interface phy mode is used to update peer phy mode to FW, which will cause a mis-behavior in FW during channel switch. Use peer phy mode, instead of interface phy mode when driver is sending WMI_PEER_PHYMODE cmd to FW. Also to make peer phy mode population to FW possible, add the following APIs to do host to FW phy mode conversion: wma_host_to_fw_phymode_160 wma_host_to_fw_phymode_11ax wma_host_to_fw_phymode Fix some kernel-doc discrepancies for the following existing functions: wma_fw_to_host_phymode wma_fw_to_host_phymode_160 wma_fw_to_host_phymode_11ax Change-Id: I6184a1735d37f648763b149795ac7930bce45346 CRs-Fixed: 2497684
This commit is contained in:
@@ -1062,10 +1062,10 @@ static void wma_mask_tx_ht_rate(tp_wma_handle wma, uint8_t *mcs_set)
|
||||
#if SUPPORT_11AX
|
||||
/**
|
||||
* wma_fw_to_host_phymode_11ax() - convert fw to host phymode for 11ax phymodes
|
||||
* @wma: wma handle
|
||||
* @phymode: phymode to convert
|
||||
*
|
||||
* Return: None
|
||||
* Return: one of the 11ax values defined in enum wlan_phymode;
|
||||
* or WLAN_PHYMODE_AUTO if the input is not an 11ax phymode
|
||||
*/
|
||||
static enum wlan_phymode wma_fw_to_host_phymode_11ax(WLAN_PHY_MODE phymode)
|
||||
{
|
||||
@@ -1100,10 +1100,10 @@ static enum wlan_phymode wma_fw_to_host_phymode_11ax(WLAN_PHY_MODE phymode)
|
||||
/**
|
||||
* wma_fw_to_host_phymode_160() - convert fw to host phymode for 160 mhz
|
||||
* phymodes
|
||||
* @wma: wma handle
|
||||
* @phymode: phymode to convert
|
||||
*
|
||||
* Return: None
|
||||
* Return: one of the 160 mhz values defined in enum wlan_phymode;
|
||||
* or WLAN_PHYMODE_AUTO if the input is not a 160 mhz phymode
|
||||
*/
|
||||
static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
|
||||
{
|
||||
@@ -1124,10 +1124,10 @@ static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
|
||||
#endif
|
||||
/**
|
||||
* wma_fw_to_host_phymode() - convert fw to host phymode
|
||||
* @wma: wma handle
|
||||
* @phymode: phymode to convert
|
||||
*
|
||||
* Return: None
|
||||
* Return: one of the values defined in enum wlan_phymode;
|
||||
* or WLAN_PHYMODE_AUTO if the conversion fails
|
||||
*/
|
||||
static enum wlan_phymode wma_fw_to_host_phymode(WLAN_PHY_MODE phymode)
|
||||
{
|
||||
@@ -1169,6 +1169,104 @@ static enum wlan_phymode wma_fw_to_host_phymode(WLAN_PHY_MODE phymode)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_160MHZ_SUPPORT
|
||||
/**
|
||||
* wma_host_to_fw_phymode_160() - convert host to fw phymode for 160 mhz
|
||||
* @host_phymode: phymode to convert
|
||||
*
|
||||
* Return: one of the 160 mhz values defined in enum WLAN_PHY_MODE;
|
||||
* or MODE_UNKNOWN if the input is not a 160 mhz phymode
|
||||
*/
|
||||
static WLAN_PHY_MODE wma_host_to_fw_phymode_160(enum wlan_phymode host_phymode)
|
||||
{
|
||||
switch (host_phymode) {
|
||||
case WLAN_PHYMODE_11AC_VHT80_80:
|
||||
return MODE_11AC_VHT80_80;
|
||||
case WLAN_PHYMODE_11AC_VHT160:
|
||||
return MODE_11AC_VHT160;
|
||||
default:
|
||||
return MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static WLAN_PHY_MODE wma_host_to_fw_phymode_160(enum wlan_phymode host_phymode)
|
||||
{
|
||||
return MODE_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SUPPORT_11AX
|
||||
/**
|
||||
* wma_host_to_fw_phymode_11ax() - convert host to fw phymode for 11ax phymode
|
||||
* @host_phymode: phymode to convert
|
||||
*
|
||||
* Return: one of the 11ax values defined in enum WLAN_PHY_MODE;
|
||||
* or MODE_UNKNOWN if the input is not an 11ax phymode
|
||||
*/
|
||||
static WLAN_PHY_MODE wma_host_to_fw_phymode_11ax(enum wlan_phymode host_phymode)
|
||||
{
|
||||
switch (host_phymode) {
|
||||
case WLAN_PHYMODE_11AXA_HE20:
|
||||
return MODE_11AX_HE20;
|
||||
case WLAN_PHYMODE_11AXA_HE40:
|
||||
return MODE_11AX_HE40;
|
||||
case WLAN_PHYMODE_11AXA_HE80:
|
||||
return MODE_11AX_HE80;
|
||||
case WLAN_PHYMODE_11AXA_HE80_80:
|
||||
return MODE_11AX_HE80_80;
|
||||
case WLAN_PHYMODE_11AXA_HE160:
|
||||
return MODE_11AX_HE160;
|
||||
default:
|
||||
return MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static WLAN_PHY_MODE wma_host_to_fw_phymode_11ax(enum wlan_phymode host_phymode)
|
||||
{
|
||||
return MODE_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wma_host_to_fw_phymode() - convert host to fw phymode
|
||||
* @host_phymode: phymode to convert
|
||||
*
|
||||
* Return: one of the values defined in enum WLAN_PHY_MODE;
|
||||
* or MODE_UNKNOWN if the conversion fails
|
||||
*/
|
||||
static WLAN_PHY_MODE wma_host_to_fw_phymode(enum wlan_phymode host_phymode)
|
||||
{
|
||||
WLAN_PHY_MODE fw_phymode;
|
||||
|
||||
switch (host_phymode) {
|
||||
case WLAN_PHYMODE_11A:
|
||||
return MODE_11A;
|
||||
case WLAN_PHYMODE_11G:
|
||||
return MODE_11G;
|
||||
case WLAN_PHYMODE_11B:
|
||||
return MODE_11B;
|
||||
case WLAN_PHYMODE_11NA_HT20:
|
||||
return MODE_11NA_HT20;
|
||||
case WLAN_PHYMODE_11NG_HT20:
|
||||
return MODE_11NG_HT20;
|
||||
case WLAN_PHYMODE_11NA_HT40:
|
||||
return MODE_11NA_HT40;
|
||||
case WLAN_PHYMODE_11NG_HT40:
|
||||
return MODE_11NG_HT40;
|
||||
case WLAN_PHYMODE_11AC_VHT20:
|
||||
return MODE_11AC_VHT20;
|
||||
case WLAN_PHYMODE_11AC_VHT40:
|
||||
return MODE_11AC_VHT40;
|
||||
case WLAN_PHYMODE_11AC_VHT80:
|
||||
return MODE_11AC_VHT80;
|
||||
default:
|
||||
fw_phymode = wma_host_to_fw_phymode_160(host_phymode);
|
||||
if (fw_phymode != MODE_UNKNOWN)
|
||||
return fw_phymode;
|
||||
return wma_host_to_fw_phymode_11ax(host_phymode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object
|
||||
* @wma: wma handle
|
||||
@@ -3433,23 +3531,53 @@ int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf,
|
||||
void wma_process_update_opmode(tp_wma_handle wma_handle,
|
||||
tUpdateVHTOpMode *update_vht_opmode)
|
||||
{
|
||||
struct wma_txrx_node *iface;
|
||||
wmi_host_channel_width ch_width;
|
||||
uint8_t pdev_id;
|
||||
struct wlan_objmgr_peer *peer;
|
||||
struct wlan_objmgr_psoc *psoc = wma_handle->psoc;
|
||||
enum wlan_phymode peer_phymode;
|
||||
WLAN_PHY_MODE fw_phymode;
|
||||
enum wlan_peer_type peer_type;
|
||||
|
||||
pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
|
||||
peer = wlan_objmgr_get_peer(psoc, pdev_id, update_vht_opmode->peer_mac,
|
||||
WLAN_LEGACY_WMA_ID);
|
||||
if (!peer) {
|
||||
WMA_LOGE("peer object invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
peer_type = wlan_peer_get_peer_type(peer);
|
||||
if (peer_type == WLAN_PEER_SELF) {
|
||||
WMA_LOGE("self peer wrongly used");
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_peer_obj_lock(peer);
|
||||
peer_phymode = wlan_peer_get_phymode(peer);
|
||||
wlan_peer_obj_unlock(peer);
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
|
||||
|
||||
fw_phymode = wma_host_to_fw_phymode(peer_phymode);
|
||||
|
||||
iface = &wma_handle->interfaces[update_vht_opmode->smesessionId];
|
||||
ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle,
|
||||
iface->chanmode);
|
||||
(WMI_HOST_WLAN_PHY_MODE)
|
||||
fw_phymode);
|
||||
WMA_LOGD("%s: peer phymode: %d, ch_width: %d, fw phymode: %d",
|
||||
__func__, peer_phymode, ch_width, fw_phymode);
|
||||
if (ch_width < update_vht_opmode->opMode) {
|
||||
WMA_LOGE("%s: Invalid peer bw update %d, self bw %d",
|
||||
__func__, update_vht_opmode->opMode,
|
||||
ch_width);
|
||||
return;
|
||||
}
|
||||
WMA_LOGD("%s: phymode = %d", __func__, iface->chanmode);
|
||||
|
||||
/* Always send phymode before BW to avoid any mismatch in FW */
|
||||
wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
|
||||
WMI_PEER_PHYMODE, iface->chanmode,
|
||||
WMI_PEER_PHYMODE, fw_phymode,
|
||||
update_vht_opmode->smesessionId);
|
||||
|
||||
WMA_LOGD("%s: opMode = %d", __func__, update_vht_opmode->opMode);
|
||||
wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
|
||||
WMI_PEER_CHWIDTH, update_vht_opmode->opMode,
|
||||
|
Reference in New Issue
Block a user