|
@@ -336,6 +336,71 @@ wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
|
|
|
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
+
|
|
|
+static uint8_t
|
|
|
+wlan_populate_band_bitmap(struct mlo_link_switch_context *link_ctx)
|
|
|
+{
|
|
|
+ uint8_t i, band_bitmap = 0, band;
|
|
|
+ struct wlan_channel *link_chan_info;
|
|
|
+
|
|
|
+ for (i = 0; i < WLAN_MAX_ML_BSS_LINKS; i++) {
|
|
|
+ link_chan_info = link_ctx->links_info[i].link_chan_info;
|
|
|
+
|
|
|
+ band = wlan_reg_freq_to_band((qdf_freq_t)
|
|
|
+ link_chan_info->ch_freq);
|
|
|
+
|
|
|
+ band_bitmap |= BIT(band);
|
|
|
+ }
|
|
|
+
|
|
|
+ return band_bitmap;
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS
|
|
|
+wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct wlan_diag_packet_info *data,
|
|
|
+ enum wlan_main_tag tag)
|
|
|
+{
|
|
|
+ struct mlo_link_switch_context *link_ctx;
|
|
|
+ struct qdf_mac_addr peer_mac;
|
|
|
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ if (!mlo_is_mld_sta(vdev))
|
|
|
+ return status;
|
|
|
+
|
|
|
+ if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+
|
|
|
+ status = wlan_vdev_get_bss_peer_mac(vdev, &peer_mac);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ logging_err("vdev: %d bss peer not found",
|
|
|
+ wlan_vdev_get_id(vdev));
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_copy(data->diag_cmn.bssid,
|
|
|
+ peer_mac.bytes,
|
|
|
+ QDF_MAC_ADDR_SIZE);
|
|
|
+
|
|
|
+ qdf_mem_copy(data->mld_addr,
|
|
|
+ wlan_vdev_mlme_get_mldaddr(vdev),
|
|
|
+ QDF_MAC_ADDR_SIZE);
|
|
|
+
|
|
|
+ if (tag == WLAN_ASSOC_REQ ||
|
|
|
+ tag == WLAN_REASSOC_REQ) {
|
|
|
+ link_ctx = vdev->mlo_dev_ctx->link_ctx;
|
|
|
+ if (!link_ctx) {
|
|
|
+ logging_debug("vdev: %d link_ctx not found",
|
|
|
+ wlan_vdev_get_id(vdev));
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ data->supported_links =
|
|
|
+ wlan_populate_band_bitmap(link_ctx);
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
#else
|
|
|
static QDF_STATUS
|
|
|
wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
|
|
@@ -343,6 +408,14 @@ wlan_populate_link_addr(struct wlan_objmgr_vdev *vdev,
|
|
|
{
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
+
|
|
|
+static QDF_STATUS
|
|
|
+wlan_populate_mlo_mgmt_event_param(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct wlan_diag_packet_info *data,
|
|
|
+ enum wlan_main_tag tag)
|
|
|
+{
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
#endif
|
|
|
|
|
|
void
|
|
@@ -389,6 +462,28 @@ out:
|
|
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+wlan_populate_vsie(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct wlan_diag_packet_info *data,
|
|
|
+ bool is_tx)
|
|
|
+{
|
|
|
+ struct element_info *vsie_info = NULL;
|
|
|
+
|
|
|
+ if (is_tx)
|
|
|
+ vsie_info = mlme_get_self_disconnect_ies(vdev);
|
|
|
+ else
|
|
|
+ vsie_info = mlme_get_peer_disconnect_ies(vdev);
|
|
|
+
|
|
|
+ if (!vsie_info)
|
|
|
+ return;
|
|
|
+
|
|
|
+ data->vsie_len = vsie_info->len;
|
|
|
+ if (data->vsie_len > MAX_VSIE_LEN)
|
|
|
+ data->vsie_len = MAX_VSIE_LEN;
|
|
|
+
|
|
|
+ qdf_mem_copy(data->vsie, vsie_info->ptr, data->vsie_len);
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
|
|
|
struct wlan_frame_hdr *mac_hdr,
|
|
@@ -402,6 +497,7 @@ wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
|
|
|
enum QDF_OPMODE opmode;
|
|
|
bool is_auth_frame_caching_required, is_initial_connection;
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
+ QDF_STATUS status;
|
|
|
|
|
|
WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info);
|
|
|
|
|
@@ -413,13 +509,14 @@ wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
|
|
|
}
|
|
|
|
|
|
opmode = wlan_vdev_mlme_get_opmode(vdev);
|
|
|
- if (opmode != QDF_STA_MODE) {
|
|
|
- wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (opmode != QDF_STA_MODE)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (mlo_is_mld_sta(vdev) &&
|
|
|
+ wlan_vdev_mlme_is_mlo_link_vdev(vdev))
|
|
|
+ goto out;
|
|
|
|
|
|
is_initial_connection = wlan_cm_is_vdev_connecting(vdev);
|
|
|
- wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
|
|
|
qdf_mem_zero(&wlan_diag_event, sizeof(struct wlan_diag_packet_info));
|
|
|
|
|
@@ -431,7 +528,13 @@ wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
|
|
|
qdf_mem_copy(wlan_diag_event.diag_cmn.bssid, &mac_hdr->i_addr3[0],
|
|
|
QDF_MAC_ADDR_SIZE);
|
|
|
|
|
|
- wlan_diag_event.version = DIAG_MGMT_VERSION;
|
|
|
+ status = wlan_populate_mlo_mgmt_event_param(vdev, &wlan_diag_event,
|
|
|
+ tag);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ wlan_diag_event.version = DIAG_MGMT_VERSION_V2;
|
|
|
+ wlan_diag_event.tx_fail_reason = tx_status;
|
|
|
wlan_diag_event.tx_status = wlan_get_diag_tx_status(tx_status);
|
|
|
wlan_diag_event.rssi = peer_rssi;
|
|
|
wlan_diag_event.sn =
|
|
@@ -442,6 +545,9 @@ wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
|
|
|
wlan_diag_event.auth_seq_num = auth_seq;
|
|
|
wlan_diag_event.assoc_id = aid;
|
|
|
|
|
|
+ if (tag == WLAN_DEAUTH_TX || tag == WLAN_DISASSOC_TX)
|
|
|
+ wlan_populate_vsie(vdev, &wlan_diag_event, true);
|
|
|
+
|
|
|
if (wlan_diag_event.subtype > WLAN_CONN_DIAG_REASSOC_RESP_EVENT &&
|
|
|
wlan_diag_event.subtype < WLAN_CONN_DIAG_BMISS_EVENT)
|
|
|
wlan_diag_event.reason = status_code;
|
|
@@ -458,5 +564,9 @@ wlan_connectivity_mgmt_event(struct wlan_objmgr_psoc *psoc,
|
|
|
wlan_cache_connectivity_log(psoc, vdev_id, &wlan_diag_event);
|
|
|
else
|
|
|
WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_MGMT);
|
|
|
+
|
|
|
+out:
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
+
|
|
|
}
|
|
|
#endif
|