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:
wadesong
2019-09-16 17:26:07 +08:00
committed by nshrivas
orang tua ac3df1e582
melakukan d3f8d3a927

Melihat File

@@ -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,