qcacld-3.0: Send chan load response to AP
If a DUT accept channel load request, the STA should response with a channel load report with channel utilization measurement as observed by the measuring STA. Change-Id: Ic8faa45e24d7cd296e44828370b1b1088d46ddda CRs-Fixed: 3580203
This commit is contained in:

committed by
Rahul Choudhary

parent
b89f7f0dde
commit
f89f0e2de0
@@ -394,6 +394,19 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
|
|||||||
struct channel_status *chan_stat,
|
struct channel_status *chan_stat,
|
||||||
uint8_t vdev_id);
|
uint8_t vdev_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_cp_stats_get_rx_clear_count() - API to get rx clear count for a channel
|
||||||
|
* @psoc: pointer to psoc
|
||||||
|
* @vdev_id: vdev id
|
||||||
|
* @channel: channel for which rx clear count require
|
||||||
|
* @chan_load: buffer to store rx clear count for a channel
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id, uint8_t channel,
|
||||||
|
uint8_t *chan_load);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ucfg_mc_cp_stats_clear_channel_status() - API to clear chan stats
|
* ucfg_mc_cp_stats_clear_channel_status() - API to clear chan stats
|
||||||
* @pdev: pointer to pdev object
|
* @pdev: pointer to pdev object
|
||||||
@@ -506,6 +519,13 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id, uint8_t channel,
|
||||||
|
uint8_t *chan_load)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void ucfg_mc_cp_stats_clear_channel_status(struct wlan_objmgr_pdev *pdev)
|
void ucfg_mc_cp_stats_clear_channel_status(struct wlan_objmgr_pdev *pdev)
|
||||||
{
|
{
|
||||||
|
@@ -1048,6 +1048,81 @@ void ucfg_mc_cp_stats_register_lost_link_info_cb(
|
|||||||
psoc_cp_stats_priv->legacy_stats_cb = lost_link_cp_stats_info_cb;
|
psoc_cp_stats_priv->legacy_stats_cb = lost_link_cp_stats_info_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef QCA_SUPPORT_CP_STATS
|
||||||
|
void wlan_cp_stats_get_rx_clear_count(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id, uint8_t channel,
|
||||||
|
uint8_t *chan_load)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_pdev *pdev;
|
||||||
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
struct pdev_cp_stats *pdev_cp_stats_priv;
|
||||||
|
struct per_channel_stats *channel_stats;
|
||||||
|
struct channel_status *channel_status_list;
|
||||||
|
uint8_t total_channel;
|
||||||
|
uint8_t i;
|
||||||
|
uint32_t rx_clear_count = 0, cycle_count = 0, mac_clk_mhz = 0;
|
||||||
|
uint64_t clock_freq, time, time_busy;
|
||||||
|
|
||||||
|
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||||
|
WLAN_CP_STATS_ID);
|
||||||
|
if (!vdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pdev = wlan_vdev_get_pdev(vdev);
|
||||||
|
if (!pdev) {
|
||||||
|
cp_stats_err("pdev object is null");
|
||||||
|
goto release_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
|
||||||
|
if (!pdev_cp_stats_priv) {
|
||||||
|
cp_stats_err("pdev cp stats object is null");
|
||||||
|
goto release_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_stats = &pdev_cp_stats_priv->pdev_stats->chan_stats;
|
||||||
|
channel_status_list = channel_stats->channel_status_list;
|
||||||
|
total_channel = channel_stats->total_channel;
|
||||||
|
|
||||||
|
for (i = 0; i < total_channel && i < NUM_CHANNELS; i++) {
|
||||||
|
if (channel_status_list[i].channel_id == channel) {
|
||||||
|
rx_clear_count = channel_status_list[i].rx_clear_count;
|
||||||
|
cycle_count = channel_status_list[i].cycle_count;
|
||||||
|
mac_clk_mhz = channel_status_list[i].mac_clk_mhz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == total_channel) {
|
||||||
|
cp_stats_debug("no channel found for chan:%d", channel);
|
||||||
|
goto release_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_freq = mac_clk_mhz * 1000;
|
||||||
|
if (clock_freq == 0) {
|
||||||
|
cp_stats_debug("clock_freq is zero");
|
||||||
|
goto release_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
time = qdf_do_div(cycle_count, clock_freq);
|
||||||
|
if (time == 0) {
|
||||||
|
cp_stats_debug("time is zero");
|
||||||
|
goto release_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_busy = qdf_do_div(rx_clear_count, clock_freq);
|
||||||
|
|
||||||
|
*chan_load = ((time_busy * 255) / time);
|
||||||
|
|
||||||
|
cp_stats_debug("t_chan:%d, chan:%d, rcc:%u, cc:%u, cf:%u, time:%u, time_busy:%u, chan_load:%d",
|
||||||
|
total_channel, channel, rx_clear_count, cycle_count,
|
||||||
|
clock_freq, time, time_busy, *chan_load);
|
||||||
|
|
||||||
|
release_ref:
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
|
#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
|
||||||
static QDF_STATUS
|
static QDF_STATUS
|
||||||
ucfg_mc_cp_stats_suspend_req_handler(struct wlan_objmgr_psoc *psoc)
|
ucfg_mc_cp_stats_suspend_req_handler(struct wlan_objmgr_psoc *psoc)
|
||||||
|
@@ -1347,6 +1347,22 @@ typedef struct sSirMacBeaconReport {
|
|||||||
|
|
||||||
} tSirMacBeaconReport, *tpSirMacBeaconReport;
|
} tSirMacBeaconReport, *tpSirMacBeaconReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct chan_load_report - channel load Report Structure
|
||||||
|
* @op_class: Regulatory Class
|
||||||
|
* @channel: Channel for which the current report is being sent
|
||||||
|
* @rrm_scan_tsf: RRM scan start time for this report
|
||||||
|
* @meas_duration: Scan duration for the current channel
|
||||||
|
* @chan_load: channel utilization measurement
|
||||||
|
*/
|
||||||
|
struct chan_load_report {
|
||||||
|
uint8_t op_class;
|
||||||
|
uint8_t channel;
|
||||||
|
qdf_time_t rrm_scan_tsf;
|
||||||
|
uint8_t meas_duration;
|
||||||
|
uint8_t chan_load;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct sSirMacRadioMeasureReport {
|
typedef struct sSirMacRadioMeasureReport {
|
||||||
uint8_t token;
|
uint8_t token;
|
||||||
uint8_t refused;
|
uint8_t refused;
|
||||||
@@ -1354,6 +1370,7 @@ typedef struct sSirMacRadioMeasureReport {
|
|||||||
uint8_t type;
|
uint8_t type;
|
||||||
union {
|
union {
|
||||||
tSirMacBeaconReport beaconReport;
|
tSirMacBeaconReport beaconReport;
|
||||||
|
struct chan_load_report channel_load_report;
|
||||||
} report;
|
} report;
|
||||||
|
|
||||||
} tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport;
|
} tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport;
|
||||||
|
@@ -86,8 +86,9 @@ enum eWniMsgTypes {
|
|||||||
eWNI_SME_BEACON_REPORT_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 45,
|
eWNI_SME_BEACON_REPORT_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 45,
|
||||||
eWNI_SME_BEACON_REPORT_RESP_XMIT_IND = SIR_SME_MSG_TYPES_BEGIN + 46,
|
eWNI_SME_BEACON_REPORT_RESP_XMIT_IND = SIR_SME_MSG_TYPES_BEGIN + 46,
|
||||||
eWNI_SME_CHAN_LOAD_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 47,
|
eWNI_SME_CHAN_LOAD_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 47,
|
||||||
|
eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND = SIR_SME_MSG_TYPES_BEGIN + 48,
|
||||||
|
|
||||||
/* unused SIR_SME_MSG_TYPES_BEGIN + 48, */
|
/* unused SIR_SME_MSG_TYPES_BEGIN + 49, */
|
||||||
eWNI_SME_FT_AGGR_QOS_REQ = SIR_SME_MSG_TYPES_BEGIN + 52,
|
eWNI_SME_FT_AGGR_QOS_REQ = SIR_SME_MSG_TYPES_BEGIN + 52,
|
||||||
eWNI_SME_FT_AGGR_QOS_RSP = SIR_SME_MSG_TYPES_BEGIN + 53,
|
eWNI_SME_FT_AGGR_QOS_RSP = SIR_SME_MSG_TYPES_BEGIN + 53,
|
||||||
|
|
||||||
|
@@ -831,6 +831,19 @@ populate_dot11f_beacon_report(struct mac_context *mac,
|
|||||||
tSirMacBeaconReport *pBeaconReport,
|
tSirMacBeaconReport *pBeaconReport,
|
||||||
bool is_last_frame);
|
bool is_last_frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* populate_dot11f_chan_load_report() - populate the chan load Report IE
|
||||||
|
* @mac: pointer to the global MAC context
|
||||||
|
* @dot11f: pointer to the measurement report structure
|
||||||
|
* @channel_load_report: pointer to the chan load Report structure
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
populate_dot11f_chan_load_report(struct mac_context *mac,
|
||||||
|
tDot11fIEMeasurementReport *dot11f,
|
||||||
|
struct chan_load_report *channel_load_report);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Populate a tDot11fIEExtSuppRates
|
* \brief Populate a tDot11fIEExtSuppRates
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2012, 2014-2021 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2011-2012, 2014-2021 The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -90,6 +91,17 @@ QDF_STATUS
|
|||||||
rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
|
rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
|
||||||
tpSirBeaconReportXmitInd beacon_xmit_ind);
|
tpSirBeaconReportXmitInd beacon_xmit_ind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rrm_process_chan_load_report_xmit() - process channel load report xmit
|
||||||
|
* @mac_ctx: Mac context
|
||||||
|
* @chan_load_ind: channel load xmit structure
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rrm_process_chan_load_report_xmit(struct mac_context *mac_ctx,
|
||||||
|
struct chan_load_xmit_ind *chan_load_ind);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rrm_get_country_code_from_connected_profile() - get country code
|
* rrm_get_country_code_from_connected_profile() - get country code
|
||||||
* from connected profile
|
* from connected profile
|
||||||
|
@@ -78,6 +78,34 @@ struct ch_load_ind {
|
|||||||
uint16_t meas_duration;
|
uint16_t meas_duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct chan_load_xmit_ind - Contains info for channel load xmit indication
|
||||||
|
* @message_type: message type eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND
|
||||||
|
* @length: size of struct chan_load_req_ind
|
||||||
|
* @measurement_idx: measurement index for channel load request
|
||||||
|
* @peer_addr: MAC address of the BSS
|
||||||
|
* @dialog_token: dialog token
|
||||||
|
* @op_class: regulatory class
|
||||||
|
* @channel: channel number
|
||||||
|
* @duration: measurement duration in ms
|
||||||
|
* @chan_load: channel utilization measurement
|
||||||
|
* @rrm_scan_tsf: time at which driver triggers rrm scan for channel load
|
||||||
|
* @is_report_success: need to send failure report or not
|
||||||
|
*/
|
||||||
|
struct chan_load_xmit_ind {
|
||||||
|
uint16_t messageType;
|
||||||
|
uint16_t length;
|
||||||
|
uint8_t measurement_idx;
|
||||||
|
struct qdf_mac_addr peer_addr;
|
||||||
|
uint16_t dialog_token;
|
||||||
|
uint8_t op_class;
|
||||||
|
uint8_t channel;
|
||||||
|
uint16_t duration;
|
||||||
|
uint8_t chan_load;
|
||||||
|
qdf_time_t rrm_scan_tsf;
|
||||||
|
bool is_report_success;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct sSirBeaconReportReqInd {
|
typedef struct sSirBeaconReportReqInd {
|
||||||
uint16_t messageType; /* eWNI_SME_BEACON_REPORT_REQ_IND */
|
uint16_t messageType; /* eWNI_SME_BEACON_REPORT_REQ_IND */
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
|
@@ -1755,6 +1755,7 @@ static void lim_process_messages(struct mac_context *mac_ctx,
|
|||||||
case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
|
case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
|
||||||
case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
|
case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
|
||||||
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
|
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
|
||||||
|
case eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND:
|
||||||
#if defined FEATURE_WLAN_ESE
|
#if defined FEATURE_WLAN_ESE
|
||||||
case eWNI_SME_ESE_ADJACENT_AP_REPORT:
|
case eWNI_SME_ESE_ADJACENT_AP_REPORT:
|
||||||
#endif
|
#endif
|
||||||
|
@@ -8018,6 +8018,9 @@ static void __lim_process_report_message(struct mac_context *mac,
|
|||||||
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
|
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
|
||||||
rrm_process_beacon_report_xmit(mac, pMsg->bodyptr);
|
rrm_process_beacon_report_xmit(mac, pMsg->bodyptr);
|
||||||
break;
|
break;
|
||||||
|
case eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND:
|
||||||
|
rrm_process_chan_load_report_xmit(mac, pMsg->bodyptr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pe_err("Invalid msg type: %d", pMsg->type);
|
pe_err("Invalid msg type: %d", pMsg->type);
|
||||||
}
|
}
|
||||||
@@ -8731,6 +8734,7 @@ bool lim_process_sme_req_messages(struct mac_context *mac,
|
|||||||
|
|
||||||
case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
|
case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
|
||||||
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
|
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
|
||||||
|
case eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND:
|
||||||
__lim_process_report_message(mac, pMsg);
|
__lim_process_report_message(mac, pMsg);
|
||||||
break;
|
break;
|
||||||
case eWNI_SME_FT_AGGR_QOS_REQ:
|
case eWNI_SME_FT_AGGR_QOS_REQ:
|
||||||
|
@@ -5676,6 +5676,16 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac,
|
|||||||
pRRMReport[i].refused;
|
pRRMReport[i].refused;
|
||||||
frm->MeasurementReport[i].present = 1;
|
frm->MeasurementReport[i].present = 1;
|
||||||
break;
|
break;
|
||||||
|
case SIR_MAC_RRM_CHANNEL_LOAD_TYPE:
|
||||||
|
populate_dot11f_chan_load_report(mac,
|
||||||
|
&frm->MeasurementReport[i],
|
||||||
|
&pRRMReport[i].report.channel_load_report);
|
||||||
|
frm->MeasurementReport[i].incapable =
|
||||||
|
pRRMReport[i].incapable;
|
||||||
|
frm->MeasurementReport[i].refused =
|
||||||
|
pRRMReport[i].refused;
|
||||||
|
frm->MeasurementReport[i].present = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
frm->MeasurementReport[i].incapable =
|
frm->MeasurementReport[i].incapable =
|
||||||
pRRMReport[i].incapable;
|
pRRMReport[i].incapable;
|
||||||
@@ -5751,14 +5761,12 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac,
|
|||||||
wlan_vdev_get_id(pe_session->vdev));
|
wlan_vdev_get_id(pe_session->vdev));
|
||||||
}
|
}
|
||||||
|
|
||||||
pe_nofl_info("TX: %s seq_no:%d dialog_token:%d no. of APs:%d is_last_rpt:%d num_report: %d peer:"QDF_MAC_ADDR_FMT,
|
pe_nofl_info("TX: type:%d seq_no:%d dialog_token:%d no. of APs:%d is_last_rpt:%d num_report:%d peer:"QDF_MAC_ADDR_FMT,
|
||||||
frm->MeasurementReport[0].type == SIR_MAC_RRM_BEACON_TYPE ?
|
frm->MeasurementReport[0].type,
|
||||||
"[802.11 BCN_RPT]" : "[802.11 RRM]",
|
|
||||||
(pMacHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET |
|
(pMacHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET |
|
||||||
pMacHdr->seqControl.seqNumLo),
|
pMacHdr->seqControl.seqNumLo),
|
||||||
dialog_token, frm->num_MeasurementReport,
|
dialog_token, frm->num_MeasurementReport,
|
||||||
is_last_report, num_report,
|
is_last_report, num_report, QDF_MAC_ADDR_REF(peer));
|
||||||
QDF_MAC_ADDR_REF(peer));
|
|
||||||
|
|
||||||
if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) ||
|
if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) ||
|
||||||
pe_session->opmode == QDF_P2P_CLIENT_MODE ||
|
pe_session->opmode == QDF_P2P_CLIENT_MODE ||
|
||||||
@@ -5775,7 +5783,7 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac,
|
|||||||
pe_session->peSessionId, qdf_status));
|
pe_session->peSessionId, qdf_status));
|
||||||
if (QDF_STATUS_SUCCESS != qdf_status) {
|
if (QDF_STATUS_SUCCESS != qdf_status) {
|
||||||
pe_nofl_err("TX: [802.11 RRM] Send FAILED! err_status [%d]",
|
pe_nofl_err("TX: [802.11 RRM] Send FAILED! err_status [%d]",
|
||||||
qdf_status);
|
qdf_status);
|
||||||
status_code = QDF_STATUS_E_FAILURE;
|
status_code = QDF_STATUS_E_FAILURE;
|
||||||
/* Pkt will be freed up by the callback */
|
/* Pkt will be freed up by the callback */
|
||||||
}
|
}
|
||||||
|
@@ -1524,6 +1524,95 @@ cleanup:
|
|||||||
rrm_cleanup(mac, index);
|
rrm_cleanup(mac, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rrm_process_chan_load_report_xmit(struct mac_context *mac_ctx,
|
||||||
|
struct chan_load_xmit_ind *chan_load_ind)
|
||||||
|
{
|
||||||
|
tSirMacRadioMeasureReport *report = NULL;
|
||||||
|
struct chan_load_report *channel_load_report;
|
||||||
|
tpRRMReq curr_req;
|
||||||
|
struct pe_session *session_entry;
|
||||||
|
uint8_t session_id, idx;
|
||||||
|
struct qdf_mac_addr sessionBssId;
|
||||||
|
|
||||||
|
if (!chan_load_ind) {
|
||||||
|
pe_err("Received chan_load_xmit_ind is NULL in PE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = chan_load_ind->measurement_idx;
|
||||||
|
|
||||||
|
if (idx >= QDF_ARRAY_SIZE(mac_ctx->rrm.rrmPEContext.pCurrentReq)) {
|
||||||
|
pe_err("Received measurement_idx is out of range: %u - %zu",
|
||||||
|
idx,
|
||||||
|
QDF_ARRAY_SIZE(mac_ctx->rrm.rrmPEContext.pCurrentReq));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq[idx];
|
||||||
|
if (!curr_req) {
|
||||||
|
pe_err("no request pending in PE");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
pe_debug("Received chan load report xmit indication on idx:%d", idx);
|
||||||
|
|
||||||
|
sessionBssId = mac_ctx->rrm.rrmSmeContext[idx].sessionBssId;
|
||||||
|
|
||||||
|
session_entry = pe_find_session_by_bssid(mac_ctx, sessionBssId.bytes,
|
||||||
|
&session_id);
|
||||||
|
if (!session_entry) {
|
||||||
|
pe_err("NULL session for bssId "QDF_MAC_ADDR_FMT"",
|
||||||
|
QDF_MAC_ADDR_REF(sessionBssId.bytes));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chan_load_ind->is_report_success) {
|
||||||
|
rrm_process_chan_load_request_failure(mac_ctx, session_entry,
|
||||||
|
sessionBssId.bytes,
|
||||||
|
eRRM_REFUSED, idx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
report = qdf_mem_malloc(sizeof(*report));
|
||||||
|
if (!report)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Prepare the channel load report and send it to the peer.*/
|
||||||
|
report->token = chan_load_ind->dialog_token;
|
||||||
|
report->refused = 0;
|
||||||
|
report->incapable = 0;
|
||||||
|
report->type = SIR_MAC_RRM_CHANNEL_LOAD_TYPE;
|
||||||
|
|
||||||
|
channel_load_report = &report[0].report.channel_load_report;
|
||||||
|
channel_load_report->op_class = chan_load_ind->op_class;
|
||||||
|
channel_load_report->channel = chan_load_ind->channel;
|
||||||
|
channel_load_report->rrm_scan_tsf = chan_load_ind->rrm_scan_tsf;
|
||||||
|
channel_load_report->meas_duration = chan_load_ind->duration;
|
||||||
|
channel_load_report->chan_load = chan_load_ind->chan_load;
|
||||||
|
|
||||||
|
pe_err("send chan load report for bssId:"QDF_MAC_ADDR_FMT" reg_class:%d, channel:%d, measStartTime:%llu, measDuration:%d, chan_load:%d",
|
||||||
|
QDF_MAC_ADDR_REF(sessionBssId.bytes),
|
||||||
|
channel_load_report->op_class,
|
||||||
|
channel_load_report->channel,
|
||||||
|
channel_load_report->rrm_scan_tsf,
|
||||||
|
channel_load_report->meas_duration,
|
||||||
|
channel_load_report->chan_load);
|
||||||
|
|
||||||
|
lim_send_radio_measure_report_action_frame(mac_ctx,
|
||||||
|
curr_req->dialog_token, 1,
|
||||||
|
true, &report[0],
|
||||||
|
sessionBssId.bytes,
|
||||||
|
session_entry);
|
||||||
|
|
||||||
|
end:
|
||||||
|
pe_debug("Measurement done idx:%d", idx);
|
||||||
|
rrm_cleanup(mac_ctx, idx);
|
||||||
|
qdf_mem_free(report);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rrm_process_chan_load_req() - process channel load request
|
* rrm_process_chan_load_req() - process channel load request
|
||||||
* @mac_ctx: Global pointer to MAC context
|
* @mac_ctx: Global pointer to MAC context
|
||||||
@@ -1870,18 +1959,21 @@ void rrm_cleanup(struct mac_context *mac, uint8_t idx)
|
|||||||
tpRRMReq cur_rrm_req = NULL;
|
tpRRMReq cur_rrm_req = NULL;
|
||||||
|
|
||||||
mac->rrm.rrmPEContext.num_active_request--;
|
mac->rrm.rrmPEContext.num_active_request--;
|
||||||
pe_debug("Beacon report cleanup idx:%d, num_active_request:%d",
|
|
||||||
idx, mac->rrm.rrmPEContext.num_active_request);
|
|
||||||
cur_rrm_req = mac->rrm.rrmPEContext.pCurrentReq[idx];
|
cur_rrm_req = mac->rrm.rrmPEContext.pCurrentReq[idx];
|
||||||
if (!cur_rrm_req)
|
if (!cur_rrm_req)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qdf_mem_free(cur_rrm_req->request.Beacon.reqIes.pElementIds);
|
if (cur_rrm_req->request.Beacon.reqIes.num) {
|
||||||
cur_rrm_req->request.Beacon.reqIes.pElementIds = NULL;
|
qdf_mem_free(cur_rrm_req->request.Beacon.reqIes.pElementIds);
|
||||||
cur_rrm_req->request.Beacon.reqIes.num = 0;
|
cur_rrm_req->request.Beacon.reqIes.pElementIds = NULL;
|
||||||
|
cur_rrm_req->request.Beacon.reqIes.num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
qdf_mem_free(cur_rrm_req);
|
qdf_mem_free(cur_rrm_req);
|
||||||
mac->rrm.rrmPEContext.pCurrentReq[idx] = NULL;
|
mac->rrm.rrmPEContext.pCurrentReq[idx] = NULL;
|
||||||
|
|
||||||
|
pe_debug("cleanup rrm req idx:%d, num_active_request:%d",
|
||||||
|
idx, mac->rrm.rrmPEContext.num_active_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -215,6 +215,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
|
|||||||
CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND);
|
CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND);
|
||||||
CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND);
|
CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND);
|
||||||
CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND);
|
CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND);
|
||||||
|
CASE_RETURN_STRING(eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND);
|
||||||
CASE_RETURN_STRING(eWNI_SME_CHAN_LOAD_REQ_IND);
|
CASE_RETURN_STRING(eWNI_SME_CHAN_LOAD_REQ_IND);
|
||||||
CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ);
|
CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ);
|
||||||
CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP);
|
CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP);
|
||||||
|
@@ -7061,6 +7061,31 @@ QDF_STATUS populate_dot11f_wfatpc(struct mac_context *mac,
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
populate_dot11f_chan_load_report(struct mac_context *mac,
|
||||||
|
tDot11fIEMeasurementReport *dot11f,
|
||||||
|
struct chan_load_report *channel_load_report)
|
||||||
|
{
|
||||||
|
dot11f->report.channel_load_report.op_class =
|
||||||
|
channel_load_report->op_class;
|
||||||
|
dot11f->report.channel_load_report.channel =
|
||||||
|
channel_load_report->channel;
|
||||||
|
qdf_mem_copy(dot11f->report.channel_load_report.meas_start_time,
|
||||||
|
&channel_load_report->rrm_scan_tsf,
|
||||||
|
sizeof(dot11f->report.channel_load_report.meas_start_time));
|
||||||
|
dot11f->report.channel_load_report.meas_duration =
|
||||||
|
channel_load_report->meas_duration;
|
||||||
|
dot11f->report.channel_load_report.chan_load =
|
||||||
|
channel_load_report->chan_load;
|
||||||
|
|
||||||
|
pe_debug("regClass %d chan %d meas_time %d meas_dur %d, chan_load %d",
|
||||||
|
dot11f->report.channel_load_report.op_class,
|
||||||
|
dot11f->report.channel_load_report.channel,
|
||||||
|
channel_load_report->rrm_scan_tsf,
|
||||||
|
dot11f->report.channel_load_report.meas_duration,
|
||||||
|
dot11f->report.channel_load_report.chan_load);
|
||||||
|
}
|
||||||
|
|
||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
populate_dot11f_beacon_report(struct mac_context *mac,
|
populate_dot11f_beacon_report(struct mac_context *mac,
|
||||||
tDot11fIEMeasurementReport *pDot11f,
|
tDot11fIEMeasurementReport *pDot11f,
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include <wlan_utility.h>
|
#include <wlan_utility.h>
|
||||||
#include <../../core/src/wlan_cm_vdev_api.h>
|
#include <../../core/src/wlan_cm_vdev_api.h>
|
||||||
#include "rrm_api.h"
|
#include "rrm_api.h"
|
||||||
|
#include "wlan_cp_stats_mc_ucfg_api.h"
|
||||||
|
|
||||||
/* Roam score for a neighbor AP will be calculated based on the below
|
/* Roam score for a neighbor AP will be calculated based on the below
|
||||||
* definitions. The calculated roam score will be used to select the
|
* definitions. The calculated roam score will be used to select the
|
||||||
@@ -713,12 +714,58 @@ end:
|
|||||||
return qdf_status;
|
return qdf_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sme_rrm_send_chan_load_report_xmit_ind() -Sends the chan load report xmit
|
||||||
|
* to PE
|
||||||
|
* @mac: global mac context
|
||||||
|
* @rrm_sme_ctx: SME rrm context for measurement request
|
||||||
|
* @vdev_id: vdev id
|
||||||
|
* @is_report_success: need to send failure report or not
|
||||||
|
*
|
||||||
|
* The sme module calls this function once it finish the scan request
|
||||||
|
* and this function send the chan load report xmit to PE.
|
||||||
|
*
|
||||||
|
* Return : None
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sme_rrm_send_chan_load_report_xmit_ind(struct mac_context *mac,
|
||||||
|
tpRrmSMEContext rrm_sme_ctx,
|
||||||
|
uint8_t vdev_id,
|
||||||
|
bool is_report_success)
|
||||||
|
{
|
||||||
|
uint8_t measurement_index = rrm_sme_ctx->measurement_idx;
|
||||||
|
struct chan_load_xmit_ind *chan_load_resp;
|
||||||
|
uint16_t length;
|
||||||
|
tpRrmSMEContext rrm_ctx = &mac->rrm.rrmSmeContext[measurement_index];
|
||||||
|
|
||||||
|
length = sizeof(struct chan_load_xmit_ind);
|
||||||
|
chan_load_resp = qdf_mem_malloc(length);
|
||||||
|
if (!chan_load_resp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
chan_load_resp->messageType = eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND;
|
||||||
|
chan_load_resp->is_report_success = is_report_success;
|
||||||
|
chan_load_resp->length = length;
|
||||||
|
chan_load_resp->measurement_idx = measurement_index;
|
||||||
|
chan_load_resp->dialog_token = rrm_ctx->token;
|
||||||
|
chan_load_resp->duration = rrm_ctx->duration[0];
|
||||||
|
chan_load_resp->op_class = rrm_ctx->regClass;
|
||||||
|
chan_load_resp->channel = rrm_ctx->chan_load_req_info.channel;
|
||||||
|
chan_load_resp->rrm_scan_tsf = rrm_ctx->chan_load_req_info.rrm_scan_tsf;
|
||||||
|
wlan_cp_stats_get_rx_clear_count(mac->psoc, vdev_id,
|
||||||
|
rrm_ctx->chan_load_req_info.channel,
|
||||||
|
&chan_load_resp->chan_load);
|
||||||
|
|
||||||
|
sme_debug("SME Sending CHAN_LOAD_REPORT_RESP_XMIT_IND to PE");
|
||||||
|
umac_send_mb_message_to_mac(chan_load_resp);
|
||||||
|
}
|
||||||
|
|
||||||
static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
|
static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
|
||||||
struct scan_event *event, void *arg)
|
struct scan_event *event, void *arg)
|
||||||
{
|
{
|
||||||
struct mac_context *mac_ctx;
|
struct mac_context *mac_ctx;
|
||||||
uint32_t scan_id;
|
uint32_t scan_id;
|
||||||
uint8_t session_id, i;
|
uint8_t vdev_id, i;
|
||||||
eCsrScanStatus scan_status = eCSR_SCAN_FAILURE;
|
eCsrScanStatus scan_status = eCSR_SCAN_FAILURE;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
tpRrmSMEContext smerrmctx;
|
tpRrmSMEContext smerrmctx;
|
||||||
@@ -729,7 +776,7 @@ static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
session_id = wlan_vdev_get_id(vdev);
|
vdev_id = wlan_vdev_get_id(vdev);
|
||||||
scan_id = event->scan_id;
|
scan_id = event->scan_id;
|
||||||
|
|
||||||
qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SME, event->type,
|
qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SME, event->type,
|
||||||
@@ -750,10 +797,24 @@ static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sme_debug("Scan completed for scan_id:%d measurement_idx:%d",
|
sme_debug("vdev: %d : Scan completed for scan_id:%d idx:%d, type:%d",
|
||||||
scan_id, smerrmctx->measurement_idx);
|
vdev_id, scan_id, smerrmctx->measurement_idx,
|
||||||
sme_rrm_scan_request_callback(mac_ctx, smerrmctx, session_id,
|
smerrmctx->measurement_type);
|
||||||
scan_id, scan_status);
|
|
||||||
|
switch (smerrmctx->measurement_type) {
|
||||||
|
case RRM_CHANNEL_LOAD:
|
||||||
|
sme_rrm_send_chan_load_report_xmit_ind(mac_ctx, smerrmctx,
|
||||||
|
vdev_id, true);
|
||||||
|
break;
|
||||||
|
case RRM_BEACON_REPORT:
|
||||||
|
sme_rrm_scan_request_callback(mac_ctx, smerrmctx, vdev_id,
|
||||||
|
scan_id, scan_status);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sme_err("Unknown measurement_type: %d",
|
||||||
|
smerrmctx->measurement_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RRM_CHAN_WEIGHT_CHAR_LEN 5
|
#define RRM_CHAN_WEIGHT_CHAR_LEN 5
|
||||||
@@ -1212,7 +1273,9 @@ error_handle:
|
|||||||
qdf_mem_free(req);
|
qdf_mem_free(req);
|
||||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
||||||
send_ind:
|
send_ind:
|
||||||
//TODO: Send channel load report xmit indication and free current req
|
sme_rrm_send_chan_load_report_xmit_ind(mac_ctx, sme_rrm_ctx,
|
||||||
|
vdev_id, false);
|
||||||
|
rrm_cleanup(mac_ctx, idx);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1491,11 +1554,14 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
|
|||||||
(uint8_t *)&beacon_req->measurementDuration,
|
(uint8_t *)&beacon_req->measurementDuration,
|
||||||
SIR_ESE_MAX_MEAS_IE_REQS);
|
SIR_ESE_MAX_MEAS_IE_REQS);
|
||||||
|
|
||||||
sme_debug("token: %d randnIntvl: %d msgSource: %d measurementduration %d, rrm_ctx duration %d Meas_mode: %s",
|
sme_rrm_ctx->measurement_type = RRM_BEACON_REPORT;
|
||||||
|
|
||||||
|
sme_debug("token: %d randnIntvl: %d msgSource: %d measurementduration %d, rrm_ctx duration %d Meas_mode: %s, type: %d",
|
||||||
sme_rrm_ctx->token, sme_rrm_ctx->randnIntvl,
|
sme_rrm_ctx->token, sme_rrm_ctx->randnIntvl,
|
||||||
sme_rrm_ctx->msgSource, beacon_req->measurementDuration[0],
|
sme_rrm_ctx->msgSource, beacon_req->measurementDuration[0],
|
||||||
sme_rrm_ctx->duration[0],
|
sme_rrm_ctx->duration[0],
|
||||||
sme_rrm_get_meas_mode_string(sme_rrm_ctx->measMode[0]));
|
sme_rrm_get_meas_mode_string(sme_rrm_ctx->measMode[0]),
|
||||||
|
sme_rrm_ctx->measurement_type);
|
||||||
|
|
||||||
return sme_rrm_issue_scan_req(mac, beacon_req->measurement_idx);
|
return sme_rrm_issue_scan_req(mac, beacon_req->measurement_idx);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user