diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 07f0d4fbf5fb..d5fe2afb7414 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -701,7 +701,6 @@ struct wma_invalid_peer_params { * @llbCoexist: 11b coexist * @shortSlotTimeSupported: is short slot time supported or not * @dtimPeriod: DTIM period - * @chanmode: channel mode * @mhz: channel frequency in KHz * @chan_width: channel bandwidth * @vdev_up: is vdev up or not @@ -755,7 +754,6 @@ struct wma_txrx_node { uint8_t llbCoexist; uint8_t shortSlotTimeSupported; uint8_t dtimPeriod; - enum wlan_phymode chanmode; A_UINT32 mhz; enum phy_ch_width chan_width; bool vdev_active; diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 2a4a0275d162..d19b5bfcb2f8 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -866,6 +866,17 @@ int wma_vdev_install_key_complete_event_handler(void *handle, uint8_t *event, uint32_t len); +/** + * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object + * @wma: wma handle + * @mac_addr: mac addr of peer + * @phymode: phymode value to set + * + * Return: None + */ +void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, uint8_t *mac_addr, + enum wlan_phymode phymode); + QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, tSirNwType nw_type, tpAddStaParams params); diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 5cab390d18b7..8c9640ffa336 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1111,12 +1111,61 @@ static void wma_handle_hidden_ssid_restart(tp_wma_handle wma, 0, NULL); } +/** + * wma_update_peer_phymode_after_vdev_restart() - for sta set new phymode to + * bss peer after vdev restart. + * @wma: wma handle + * @iface: interfcae pointer + * + * Return: none + */ +static +void wma_update_peer_phymode_after_vdev_restart(tp_wma_handle wma, + struct wma_txrx_node *iface) +{ + wmi_host_channel_width ch_width; + uint8_t vdev_id; + enum wlan_phymode bss_phymode; + uint32_t fw_phymode; + uint8_t *bssid; + struct wlan_channel *des_chan; + QDF_STATUS status; + + vdev_id = wlan_vdev_get_id(iface->vdev); + /* for CSA case firmware expects phymode before ch_wd */ + bssid = wma_get_vdev_bssid(iface->vdev); + if (!bssid) { + WMA_LOGE("%s:Failed to get bssid for vdev_id %d", + __func__, vdev_id); + return; + } + + des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev); + bss_phymode = des_chan->ch_phymode; + + /* update new phymode to peer */ + wma_objmgr_set_peer_mlme_phymode(wma, bssid, bss_phymode); + fw_phymode = wma_host_to_fw_phymode(bss_phymode); + + /* for CSA case firmware expects phymode before ch_wd */ + status = wma_set_peer_param(wma, bssid, WMI_PEER_PHYMODE, fw_phymode, + vdev_id); + WMA_LOGD("%s:vdev_id %d fw_phy_mode %d bss_phymode %d status %d", + __func__, vdev_id, fw_phymode, bss_phymode, status); + + ch_width = wmi_get_ch_width_from_phy_mode(wma->wmi_handle, fw_phymode); + status = wma_set_peer_param(wma, bssid, WMI_PEER_CHWIDTH, ch_width, + vdev_id); + WMA_LOGD("%s:vdev_id %d chanwidth %d status %d", __func__, vdev_id, + ch_width, status); +} + + QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, struct vdev_start_response *rsp) { enum wlan_vdev_sm_evt event; struct wma_txrx_node *iface; - uint8_t *bssid; iface = &wma->interfaces[rsp->vdev_id]; WMA_LOGD("%s: Send channel switch resp vdev %d status %d", @@ -1132,38 +1181,10 @@ QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, return QDF_STATUS_SUCCESS; } - if ((QDF_IS_STATUS_SUCCESS(rsp->status) && - rsp->resp_type == WMI_VDEV_RESTART_RESP_EVENT && - (iface->type == WMI_VDEV_TYPE_STA || - iface->type == WMI_VDEV_TYPE_MONITOR)) || - (rsp->resp_type == WMI_VDEV_START_RESP_EVENT && - iface->type == WMI_VDEV_TYPE_MONITOR)) { - wmi_host_channel_width chanwidth; - int err; - WMI_HOST_WLAN_PHY_MODE phy_mode; - - /* for CSA case firmware expects phymode before ch_wd */ - bssid = wma_get_vdev_bssid(iface->vdev); - if (!bssid) { - WMA_LOGE("%s:Failed to get bssid for vdev_id %d", - __func__, rsp->vdev_id); - return QDF_STATUS_E_FAILURE; - } - phy_mode = wma_host_to_fw_phymode(iface->chanmode); - - /* for CSA case firmware expects phymode before ch_wd */ - err = wma_set_peer_param(wma, bssid, WMI_PEER_PHYMODE, - phy_mode, rsp->vdev_id); - WMA_LOGD("%s:vdev_id %d fw_phy_mode %d chanmode %d status %d", - __func__, rsp->vdev_id, phy_mode, - iface->chanmode, err); - chanwidth = wmi_get_ch_width_from_phy_mode(wma->wmi_handle, - phy_mode); - err = wma_set_peer_param(wma, bssid, WMI_PEER_CHWIDTH, - chanwidth, rsp->vdev_id); - WMA_LOGD("%s:vdev_id %d chanwidth %d status %d", - __func__, rsp->vdev_id, chanwidth, err); - } + if (QDF_IS_STATUS_SUCCESS(rsp->status) && + rsp->resp_type == WMI_VDEV_RESTART_RESP_EVENT && + iface->type == WMI_VDEV_TYPE_STA) + wma_update_peer_phymode_after_vdev_restart(wma, iface); if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) || mlme_is_chan_switch_in_progress(iface->vdev)) @@ -2822,7 +2843,6 @@ QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart) return QDF_STATUS_E_FAILURE; } - intr[vdev_id].chanmode = des_chan->ch_phymode; intr[vdev_id].config.gtx_info.gtxRTMask[0] = CFG_TGT_DEFAULT_GTX_HT_MASK; intr[vdev_id].config.gtx_info.gtxRTMask[1] = diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 75deb26c9d25..98d741c6f111 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2076,7 +2076,6 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size) "\tipv6_mcast_na %u\n" "\toem_response %u\n" "dtimPeriod %d\n" - "chanmode %d\n" "chan_width %d\n" "vdev_active %d\n" "vdev_up %d\n" @@ -2104,7 +2103,6 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size) stats.ipv6_mcast_na_stats, stats.oem_response_wake_up_count, iface->dtimPeriod, - iface->chanmode, iface->chan_width, iface->vdev_active, wma_is_vdev_up(vdev_id), diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 977eaa52c768..bd458e1b7115 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1278,17 +1278,8 @@ WMI_HOST_WLAN_PHY_MODE wma_host_to_fw_phymode(enum wlan_phymode host_phymode) } } -/** - * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object - * @wma: wma handle - * @mac_addr: mac addr of peer - * @phymode: phymode value to set - * - * Return: None - */ -static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, - uint8_t *mac_addr, - enum wlan_phymode phymode) +void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, uint8_t *mac_addr, + enum wlan_phymode phymode) { uint8_t pdev_id; struct wlan_objmgr_peer *peer; @@ -1360,12 +1351,13 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, wmi_rate_set peer_legacy_rates, peer_ht_rates; uint32_t num_peer_11b_rates = 0; uint32_t num_peer_11a_rates = 0; - enum wlan_phymode phymode; + enum wlan_phymode phymode, vdev_phymode; uint32_t peer_nss = 1; struct wma_txrx_node *intr = NULL; bool is_he; QDF_STATUS status; struct mac_context *mac = wma->mac_context; + struct wlan_channel *des_chan; cmd = qdf_mem_malloc(sizeof(struct peer_assoc_params)); if (!cmd) { @@ -1400,10 +1392,13 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, phymode = wma_peer_phymode(nw_type, params->staType, params->htCapable, params->ch_width, params->vhtCapable, is_he); - if ((intr->type == WMI_VDEV_TYPE_AP) && (phymode > intr->chanmode)) { + + des_chan = wlan_vdev_mlme_get_des_chan(intr->vdev); + vdev_phymode = des_chan->ch_phymode; + if ((intr->type == WMI_VDEV_TYPE_AP) && (phymode > vdev_phymode)) { WMA_LOGD("Peer phymode %d is not allowed. Set it equal to sap/go phymode %d", - phymode, intr->chanmode); - phymode = intr->chanmode; + phymode, vdev_phymode); + phymode = vdev_phymode; } if (!mac->mlme_cfg->rates.disable_abg_rate_txdata) { @@ -3567,41 +3562,34 @@ void wma_process_update_opmode(tp_wma_handle wma_handle, enum wlan_phymode peer_phymode; uint32_t fw_phymode; enum wlan_peer_type peer_type; - struct wma_txrx_node *iface; - iface = &wma_handle->interfaces[update_vht_opmode->smesessionId]; - - if (iface->type == WMI_VDEV_TYPE_STA) { - fw_phymode = iface->chanmode; - } else { - 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); + 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); + ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle, fw_phymode); - WMA_LOGD("%s: ch_width: %d, fw phymode: %d", __func__, - ch_width, fw_phymode); + WMA_LOGD("%s: ch_width: %d, fw phymode: %d peer_phymode %d", __func__, + ch_width, fw_phymode, peer_phymode); if (ch_width < update_vht_opmode->opMode) { WMA_LOGE("%s: Invalid peer bw update %d, self bw %d", __func__, update_vht_opmode->opMode, diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index de3fc4476a75..0e2f92673c31 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2749,6 +2749,35 @@ wma_roam_update_vdev(tp_wma_handle wma, qdf_mem_free(add_sta_params); } +static void wma_update_phymode_on_roam(tp_wma_handle wma, uint8_t *bssid, + wmi_channel *chan, + struct wma_txrx_node *iface) +{ + enum wlan_phymode bss_phymode; + struct wlan_channel *des_chan; + struct vdev_mlme_obj *vdev_mlme; + uint8_t channel; + + channel = wlan_freq_to_chan(iface->mhz); + if (chan) + bss_phymode = + wma_fw_to_host_phymode(WMI_GET_CHANNEL_MODE(chan)); + else + wma_get_phy_mode_cb(channel, iface->chan_width, &bss_phymode); + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev); + + des_chan->ch_phymode = bss_phymode; + /* Till conversion is not done in WMI we need to fill fw phy mode */ + vdev_mlme->mgmt.generic.phy_mode = wma_host_to_fw_phymode(bss_phymode); + + /* update new phymode to peer */ + wma_objmgr_set_peer_mlme_phymode(wma, bssid, bss_phymode); + + WMA_LOGD("LFR3: new phymode %d", bss_phymode); +} + int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event, uint32_t len) { @@ -2757,7 +2786,6 @@ int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event, tp_wma_handle wma = (tp_wma_handle) handle; struct roam_offload_synch_ind *roam_synch_ind_ptr = NULL; struct bss_description *bss_desc_ptr = NULL; - uint8_t channel; uint16_t ie_len = 0; int status = -EINVAL; struct roam_offload_scan_req *roam_req; @@ -2951,24 +2979,15 @@ int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event, roam_synch_ind_ptr->join_rsp->vht_channel_width; /* * update phy_mode in wma to avoid mismatch in phymode between host and - * firmware. The phymode stored in interface[vdev_id].chanmode is sent - * to firmware as part of opmode update during either - vht opmode + * firmware. The phymode stored in peer->peer_mlme.phymode is + * sent to firmware as part of opmode update during either - vht opmode * action frame received or during opmode change detected while * processing beacon. Any mismatch of this value with firmware phymode * results in firmware assert. */ - channel = wlan_freq_to_chan(wma->interfaces[synch_event->vdev_id].mhz); - if (param_buf->chan) { - wma->interfaces[synch_event->vdev_id].chanmode = - wma_fw_to_host_phymode( - WMI_GET_CHANNEL_MODE(param_buf->chan)); - } else { - wma_get_phy_mode_cb(channel, - wma->interfaces[synch_event->vdev_id]. - chan_width, - &wma->interfaces[synch_event->vdev_id]. - chanmode); - } + wma_update_phymode_on_roam(wma, roam_synch_ind_ptr->bssid.bytes, + param_buf->chan, + &wma->interfaces[synch_event->vdev_id]); wma->csr_roam_synch_cb(wma->mac_context, roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_COMPLETE);