diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 7f2e73bbddaf..a2a45c591ae0 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -56,9 +56,11 @@ struct wlan_ies { /** * struct peer_mlme_priv_obj - peer MLME component object * @ucast_key_cipher: unicast crypto type. + * @is_pmf_enabled: True if PMF is enabled */ struct peer_mlme_priv_obj { uint32_t ucast_key_cipher; + bool is_pmf_enabled; }; /** @@ -341,4 +343,23 @@ void mlme_free_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev); * Return: Returns a pointer to the peer disconnect IEs present in vdev object */ struct wlan_ies *mlme_get_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_set_peer_pmf_status() - set pmf status of peer + * @peer: PEER object + * @is_pmf_enabled: Carries if PMF is enabled or not + * + * is_pmf_enabled will be set to true if PMF is enabled by peer + * + * Return: void + */ +void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, + bool is_pmf_enabled); +/** + * mlme_get_peer_pmf_status() - get if peer is of pmf capable + * @peer: PEER object + * + * Return: Value of is_pmf_enabled; True if PMF is enabled by peer + */ +bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer); #endif diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 5998199009f1..ac0532584ead 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -187,20 +187,6 @@ QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, return QDF_STATUS_SUCCESS; } -QDF_STATUS -mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer, - void *arg) -{ - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS -mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, - void *arg) -{ - return QDF_STATUS_SUCCESS; -} - #else QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, @@ -236,6 +222,7 @@ QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, return QDF_STATUS_SUCCESS; } +#endif QDF_STATUS mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer, @@ -298,7 +285,6 @@ mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, return status; } -#endif static void mlme_init_chainmask_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_chainmask *chainmask_info) @@ -2496,3 +2482,31 @@ struct wlan_ies *mlme_get_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev) return &mlme_priv->peer_disconnect_ies; } + +void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, + bool is_pmf_enabled) +{ + struct peer_mlme_priv_obj *peer_priv; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + if (!peer_priv) { + mlme_legacy_err(" peer mlme component object is NULL"); + return; + } + peer_priv->is_pmf_enabled = is_pmf_enabled; +} + +bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer) +{ + struct peer_mlme_priv_obj *peer_priv; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + if (!peer_priv) { + mlme_legacy_err("peer mlme component object is NULL"); + return false; + } + + return peer_priv->is_pmf_enabled; +} diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 129ac360924e..1623ae5adc91 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2607,11 +2607,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, * map, normal tx unmap is enough for this case. */ QDF_NBUF_CB_TX_DMA_BI_MAP((qdf_nbuf_t)tx_frame) = 1; - } else if (iface && !iface->rmfEnabled) { - if (pFc->wep && (frmType == TXRX_FRM_802_11_MGMT)) { - wma_err("PMF is disabled, but WEP is set"); - pFc->wep = 0; - } } #endif /* WLAN_FEATURE_11W */ mHdr = (tpSirMacMgmtHdr)qdf_nbuf_data(tx_frame); diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 9127dfc145e1..e6b0894f6f3f 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -3805,10 +3805,46 @@ static void wma_set_mgmt_frame_protection(tp_wma_handle wma) WMA_LOGD("%s: QOS MFP/PMF set", __func__); } } + +/** + * wma_set_peer_pmf_status() - Get the peer and update PMF capability of it + * @wma: wma handle + * @peer_mac: peer mac addr + * @is_pmf_enabled: Carries the status whether PMF is enabled or not + * + * Return: QDF_STATUS + */ +static QDF_STATUS +wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac, + bool is_pmf_enabled) +{ + struct wlan_objmgr_peer *peer; + + peer = wlan_objmgr_get_peer(wma->psoc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + peer_mac, WLAN_LEGACY_WMA_ID); + if (!peer) { + WMA_LOGE("Peer of peer_mac %pM not found", + peer_mac); + return QDF_STATUS_E_INVAL; + } + mlme_set_peer_pmf_status(peer, is_pmf_enabled); + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + WMA_LOGD("set is_pmf_enabled %d for %pM", is_pmf_enabled, peer_mac); + + return QDF_STATUS_SUCCESS; +} #else static inline void wma_set_mgmt_frame_protection(tp_wma_handle wma) { } + +static QDF_STATUS +wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac, + bool is_pmf_enabled) +{ + return QDF_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_11W */ /** @@ -4155,6 +4191,8 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, struct bss_params *add_bss) iface->llbCoexist = add_bss->llbCoexist; iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported; iface->nwType = add_bss->nwType; + if (add_bss->rmfEnabled) + wma_set_peer_pmf_status(wma, add_bss->bssId, true); if (add_bss->nonRoamReassoc) { peer = cdp_peer_find_by_addr(soc, pdev, add_bss->bssId, @@ -4611,6 +4649,9 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) } } #endif + if (add_sta->rmfEnabled) + wma_set_peer_pmf_status(wma, add_sta->staMac, true); + if (add_sta->uAPSD) { status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId, add_sta->staMac, diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 74f5d77bb89f..971ee359664c 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3941,16 +3941,94 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle, } return 0; } + +/** + * wma_get_peer_pmf_status() - Get the PMF capability of peer + * @wma: wma handle + * @peer_mac: peer mac addr + * + * Return: True if PMF is enabled, false otherwise. + */ +static bool +wma_get_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac) +{ + struct wlan_objmgr_peer *peer; + bool is_pmf_enabled; + + if (!peer_mac) { + WMA_LOGE("peer_mac is NULL"); + return false; + } + + peer = wlan_objmgr_get_peer(wma->psoc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + peer_mac, WLAN_LEGACY_WMA_ID); + if (!peer) { + WMA_LOGE("Peer of peer_mac %pM not found", + peer_mac); + return false; + } + is_pmf_enabled = mlme_get_peer_pmf_status(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + WMA_LOGD("get is_pmf_enabled %d for %pM", is_pmf_enabled, peer_mac); + + return is_pmf_enabled; +} + +/** + * wma_check_and_process_rmf_frame() - Process the frame if it is of rmf type + * @wma_handle: wma handle + * @vdev_id: vdev id + * @wh: double pointer to 802.11 frame header which will be updated if the + * frame is of rmf type. + * @rx_pkt: rx packet + * @buf: Buffer + * + * Process the frame as rmf frame only if both DUT and peer are of PMF capable + * + * Return: 0 for success or error code + */ +static int +wma_check_and_process_rmf_frame(tp_wma_handle wma_handle, + uint8_t vdev_id, + struct ieee80211_frame **wh, + cds_pkt_t *rx_pkt, + qdf_nbuf_t buf) +{ + int status; + struct wma_txrx_node *iface; + struct ieee80211_frame *hdr = *wh; + + iface = &(wma_handle->interfaces[vdev_id]); + if (!iface->rmfEnabled) + return 0; + + if (qdf_is_macaddr_group((struct qdf_mac_addr *)(hdr->i_addr1)) || + qdf_is_macaddr_broadcast((struct qdf_mac_addr *)(hdr->i_addr1)) || + wma_get_peer_pmf_status(wma_handle, hdr->i_addr2)) { + status = wma_process_rmf_frame(wma_handle, iface, hdr, + rx_pkt, buf); + if (status) + return status; + /* + * CCMP header might have been pulled off reinitialize the + * start pointer of mac header + */ + *wh = (struct ieee80211_frame *)qdf_nbuf_data(buf); + } + + return 0; +} #else -static inline int wma_process_rmf_frame(tp_wma_handle wma_handle, - struct wma_txrx_node *iface, - struct ieee80211_frame *wh, - cds_pkt_t *rx_pkt, - qdf_nbuf_t wbuf) +static inline int +wma_check_and_process_rmf_frame(tp_wma_handle wma_handle, + uint8_t vdev_id, + struct ieee80211_frame **wh, + cds_pkt_t *rx_pkt, + qdf_nbuf_t buf) { return 0; } - #endif /** @@ -3988,7 +4066,6 @@ int wma_form_rx_packet(qdf_nbuf_t buf, struct mgmt_rx_event_params *mgmt_rx_params, cds_pkt_t *rx_pkt) { - struct wma_txrx_node *iface = NULL; uint8_t vdev_id = WMA_INVALID_VDEV_ID; struct ieee80211_frame *wh; uint8_t mgt_type, mgt_subtype; @@ -4132,19 +4209,13 @@ int wma_form_rx_packet(qdf_nbuf_t buf, mgt_subtype == MGMT_SUBTYPE_ACTION)) { if (wma_find_vdev_by_bssid( wma_handle, wh->i_addr3, &vdev_id)) { - iface = &(wma_handle->interfaces[vdev_id]); - if (iface->rmfEnabled) { - status = wma_process_rmf_frame(wma_handle, - iface, wh, rx_pkt, buf); - if (status != 0) - return status; - /* - * CCMP header might have been pulled off - * reinitialize the start pointer of mac header - */ - wh = (struct ieee80211_frame *) - qdf_nbuf_data(buf); - } + status = wma_check_and_process_rmf_frame(wma_handle, + vdev_id, + &wh, + rx_pkt, + buf); + if (status) + return status; } }