qcacld-3.0: Store and send keys after peer assoc

For STA mlo connection the AP might send M1 right after assoc
response on assoc link which can result in keys sent down to FW
for mlo links before host has sent wmi_peer_assoc for link vdev.
Current code does not have handling for this case.

To solve this, store the keys and once connection is completed
on link vdev send keys.

Change-Id: I3675451ef0e047caf8c77d256ea67f0eac6ed797
CRs-Fixed: 3289589
This commit is contained in:
Amruta Kulkarni
2022-09-15 15:11:09 -07:00
committed by Madan Koyyalamudi
parent ae589ada18
commit 40598153fa
9 changed files with 300 additions and 4 deletions

View File

@@ -1491,6 +1491,56 @@ static void cm_process_connect_complete(struct wlan_objmgr_psoc *psoc,
}
static void
cm_install_link_vdev_keys(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_peer *peer;
struct wlan_crypto_key *crypto_key;
enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev);
uint16_t i;
bool pairwise;
uint8_t vdev_id;
uint16_t max_key_index = WLAN_CRYPTO_MAXKEYIDX +
WLAN_CRYPTO_MAXIGTKKEYIDX +
WLAN_CRYPTO_MAXBIGTKKEYIDX;
if (!vdev)
return;
vdev_id = wlan_vdev_get_id(vdev);
if (op_mode != QDF_STA_MODE ||
!wlan_vdev_mlme_is_mlo_link_vdev(vdev))
return;
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_CM_ID);
if (!peer) {
mlo_err("Peer is null return");
return;
}
if (!mlo_get_keys_saved(vdev, wlan_peer_get_macaddr(peer))) {
mlo_debug("keys are not saved for vdev_id %d", vdev_id);
wlan_objmgr_peer_release_ref(peer, WLAN_MLME_CM_ID);
return;
}
for (i = 0; i < max_key_index; i++) {
crypto_key = wlan_crypto_get_key(vdev, i);
if (!crypto_key)
continue;
pairwise = crypto_key->key_type ? WLAN_CRYPTO_KEY_TYPE_UNICAST : WLAN_CRYPTO_KEY_TYPE_GROUP;
mlo_debug("MLO:send keys for vdev_id %d, key_idx %d, pairwise %d",
vdev_id, i, pairwise);
mlme_cm_osif_send_keys(vdev, i, pairwise,
crypto_key->cipher_type);
}
mlo_set_keys_saved(vdev,
(struct qdf_mac_addr *)wlan_peer_get_macaddr(peer),
false);
wlan_objmgr_peer_release_ref(peer, WLAN_MLME_CM_ID);
}
QDF_STATUS
cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp)
@@ -1532,7 +1582,9 @@ cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev,
psoc, vdev_id);
else
policy_mgr_incr_active_session(psoc, op_mode, vdev_id);
cm_process_connect_complete(psoc, pdev, vdev, rsp);
cm_install_link_vdev_keys(vdev);
wlan_tdls_notify_sta_connect(vdev_id,
mlme_get_tdls_chan_switch_prohibited(vdev),
mlme_get_tdls_prohibited(vdev),

View File

@@ -241,6 +241,18 @@ QDF_STATUS
wlan_mlo_roam_abort_on_link(struct wlan_objmgr_psoc *psoc,
uint8_t *event, uint8_t vdev_id);
/**
* mlo_check_if_all_links_up - Check if all links are up
* @vdev: vdev pointer
*
* This api will check if all the requested links are in CM connected
* state.
*
* Return: QDF_STATUS
*/
bool
mlo_check_if_all_links_up(struct wlan_objmgr_vdev *vdev);
#else /* WLAN_FEATURE_11BE_MLO */
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
static inline
@@ -336,5 +348,11 @@ mlo_roam_get_bssid_chan_for_link(uint8_t vdev_id,
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline bool
mlo_check_if_all_links_up(struct wlan_objmgr_vdev *vdev)
{
return false;
}
#endif /* WLAN_FEATURE_11BE_MLO */
#endif

View File

@@ -581,3 +581,37 @@ mlo_roam_get_bssid_chan_for_link(uint8_t vdev_id,
return status;
}
bool
mlo_check_if_all_links_up(struct wlan_objmgr_vdev *vdev)
{
struct wlan_mlo_dev_context *mlo_dev_ctx;
struct wlan_mlo_sta *sta_ctx;
uint8_t i;
if (!vdev || !vdev->mlo_dev_ctx) {
mlo_err("Vdev is null");
return false;
}
mlo_dev_ctx = vdev->mlo_dev_ctx;
sta_ctx = mlo_dev_ctx->sta_ctx;
for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
if (!mlo_dev_ctx->wlan_vdev_list[i])
continue;
if (qdf_test_bit(i, sta_ctx->wlan_connected_links) &&
!wlan_cm_is_vdev_connected(mlo_dev_ctx->wlan_vdev_list[i])) {
mlo_debug("Vdev id %d is not in connected state",
wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]));
return false;
}
}
if (i == WLAN_UMAC_MLO_MAX_VDEVS) {
mlo_debug("all links are up");
return true;
}
return false;
}