qcacld-3.0: Send beacon frame in wmi_roam_invoke_cmd

Send beacon frame in wmi_roam_invoke_cmd to firmware.
This helps firmware skip scan to connect to requested
BSSID.

Change-Id: I5c6e375309dcb3bdd6430a3d501bade5cfe2e88d
CRs-Fixed: 1116901
This commit is contained in:
Naveen Rawat
2017-01-19 17:58:14 -08:00
gecommit door qcabuildsw
bovenliggende e96ee3f98e
commit 664a7cb3c6
9 gewijzigde bestanden met toevoegingen van 218 en 15 verwijderingen

Bestand weergeven

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -343,10 +343,10 @@ int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, struct qdf_mac_addr *addr);
QDF_STATUS hdd_roam_deregister_sta(hdd_adapter_t *adapter, uint8_t sta_id);
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
void hdd_wma_send_fastreassoc_cmd(int session_id, const tSirMacAddr bssid,
int channel);
void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter,
const tSirMacAddr bssid, int channel);
#else
static inline void hdd_wma_send_fastreassoc_cmd(int sessionId,
static inline void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter,
const tSirMacAddr bssid, int channel)
{
}

Bestand weergeven

@@ -785,9 +785,12 @@ static int hdd_parse_reassoc_command_v1_data(const uint8_t *pValue,
}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
void hdd_wma_send_fastreassoc_cmd(int sessionId, const tSirMacAddr bssid,
int channel)
void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter,
const tSirMacAddr bssid, int channel)
{
QDF_STATUS status;
hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
tCsrRoamProfile *profile = &wext_state->roamProfile;
struct wma_roam_invoke_cmd *fastreassoc;
struct scheduler_msg msg = {0};
@@ -796,7 +799,7 @@ void hdd_wma_send_fastreassoc_cmd(int sessionId, const tSirMacAddr bssid,
hdd_err("qdf_mem_malloc failed for fastreassoc");
return;
}
fastreassoc->vdev_id = sessionId;
fastreassoc->vdev_id = adapter->sessionId;
fastreassoc->channel = channel;
fastreassoc->bssid[0] = bssid[0];
fastreassoc->bssid[1] = bssid[1];
@@ -805,13 +808,23 @@ void hdd_wma_send_fastreassoc_cmd(int sessionId, const tSirMacAddr bssid,
fastreassoc->bssid[4] = bssid[4];
fastreassoc->bssid[5] = bssid[5];
status = sme_get_beacon_frm(WLAN_HDD_GET_HAL_CTX(adapter), profile,
bssid, &fastreassoc->frame_buf,
&fastreassoc->frame_len);
if (QDF_STATUS_SUCCESS != status) {
hdd_err("sme_get_beacon_frm failed");
fastreassoc->frame_buf = NULL;
fastreassoc->frame_len = 0;
}
msg.type = SIR_HAL_ROAM_INVOKE;
msg.reserved = 0;
msg.bodyptr = fastreassoc;
if (QDF_STATUS_SUCCESS != scheduler_post_msg(QDF_MODULE_ID_WMA,
&msg)) {
qdf_mem_free(fastreassoc);
status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg);
if (QDF_STATUS_SUCCESS != status) {
hdd_err("Not able to post ROAM_INVOKE_CMD message to WMA");
qdf_mem_free(fastreassoc);
}
}
#endif
@@ -875,7 +888,7 @@ int hdd_reassoc(hdd_adapter_t *adapter, const uint8_t *bssid,
/* Proceed with reassoc */
if (roaming_offload_enabled(hdd_ctx)) {
hdd_wma_send_fastreassoc_cmd((int)adapter->sessionId,
hdd_wma_send_fastreassoc_cmd(adapter,
bssid, (int)channel);
} else {
tCsrHandoffRequest handoffInfo;
@@ -4405,7 +4418,7 @@ static int drv_cmd_fast_reassoc(hdd_adapter_t *adapter,
QDF_MAC_ADDR_SIZE)) {
hdd_info("Reassoc BSSID is same as currently associated AP bssid");
if (roaming_offload_enabled(hdd_ctx)) {
hdd_wma_send_fastreassoc_cmd((int)adapter->sessionId,
hdd_wma_send_fastreassoc_cmd(adapter,
targetApBssid,
pHddStaCtx->conn_info.operationChannel);
} else {
@@ -4426,7 +4439,7 @@ static int drv_cmd_fast_reassoc(hdd_adapter_t *adapter,
}
if (roaming_offload_enabled(hdd_ctx)) {
hdd_wma_send_fastreassoc_cmd((int)adapter->sessionId,
hdd_wma_send_fastreassoc_cmd(adapter,
targetApBssid, (int)channel);
goto exit;
}

Bestand weergeven

@@ -8422,7 +8422,7 @@ static int __iw_setnone_getnone(struct net_device *dev,
qdf_mem_copy(bssid,
&adapter->sessionCtx.station.conn_info.bssId,
sizeof(bssid));
hdd_wma_send_fastreassoc_cmd((int)adapter->sessionId,
hdd_wma_send_fastreassoc_cmd(adapter,
bssid, operating_ch);
} else {
sme_roam_reassoc(hdd_ctx->hHal, adapter->sessionId,

Bestand weergeven

@@ -1398,4 +1398,20 @@ QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info);
*/
void sme_set_chan_info_callback(tHalHandle hal_handle,
void (*callback)(struct scan_chan_info *chan_info));
/**
* sme_get_beacon_frm() - gets the bss descriptor from scan cache and prepares
* beacon frame
* @hal: handle returned by mac_open
* @profile: current connected profile
* @bssid: bssid to look for in scan cache
* @frame_buf: frame buffer to populate
* @frame_len: length of constructed frame
*
* Return: QDF_STATUS
*/
QDF_STATUS sme_get_beacon_frm(tHalHandle hal, tCsrRoamProfile *profile,
const tSirMacAddr bssid,
uint8_t **frame_buf, uint32_t *frame_len);
#endif /* #if !defined( __SME_API_H ) */

Bestand weergeven

@@ -16981,3 +16981,129 @@ QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
return status;
}
#endif
/**
* sme_prepare_beacon_from_bss_descp() - prepares beacon frame by populating
* different fields and IEs from bss descriptor.
* @frame_buf: frame buffer to populate
* @bss_descp: bss descriptor
* @bssid: bssid of the beacon frame to populate
* @ie_len: length of IE fields
*
* Return: None
*/
static void sme_prepare_beacon_from_bss_descp(uint8_t *frame_buf,
tSirBssDescription *bss_descp,
const tSirMacAddr bssid,
uint8_t ie_len)
{
tDot11fBeacon1 *bcn_fixed;
tpSirMacMgmtHdr mac_hdr = (tpSirMacMgmtHdr)frame_buf;
/* populate mac header first to indicate beacon */
mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
mac_hdr->fc.type = SIR_MAC_MGMT_FRAME;
mac_hdr->fc.subType = SIR_MAC_MGMT_BEACON;
qdf_mem_copy((uint8_t *) mac_hdr->da,
(uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF",
sizeof(struct qdf_mac_addr));
qdf_mem_copy((uint8_t *) mac_hdr->sa, bssid,
sizeof(struct qdf_mac_addr));
qdf_mem_copy((uint8_t *) mac_hdr->bssId, bssid,
sizeof(struct qdf_mac_addr));
/* now populate fixed params */
bcn_fixed = (tDot11fBeacon1 *)(frame_buf + SIR_MAC_HDR_LEN_3A);
/* populate timestamp */
qdf_mem_copy(&bcn_fixed->TimeStamp.timestamp, &bss_descp->timeStamp,
sizeof(bss_descp->timeStamp));
/* populate beacon interval */
bcn_fixed->BeaconInterval.interval = bss_descp->beaconInterval;
/* populate capability */
qdf_mem_copy(&bcn_fixed->Capabilities, &bss_descp->capabilityInfo,
sizeof(bss_descp->capabilityInfo));
/* copy IEs now */
qdf_mem_copy(frame_buf + SIR_MAC_HDR_LEN_3A
+ SIR_MAC_B_PR_SSID_OFFSET,
&bss_descp->ieFields, ie_len);
}
QDF_STATUS sme_get_beacon_frm(tHalHandle hal, tCsrRoamProfile *profile,
const tSirMacAddr bssid,
uint8_t **frame_buf, uint32_t *frame_len)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
tScanResultHandle result_handle;
tCsrScanResultFilter *scan_filter;
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
tSirBssDescription *bss_descp;
tScanResultList *bss_list;
uint32_t ie_len;
scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
if (NULL == scan_filter) {
sms_log(mac_ctx, LOGE, FL("memory allocation failed"));
status = QDF_STATUS_E_NOMEM;
goto free_scan_flter;
}
status = csr_roam_prepare_filter_from_profile(mac_ctx,
profile, scan_filter);
if (QDF_IS_STATUS_ERROR(status)) {
sms_log(mac_ctx, LOGE, FL("prepare_filter failed"));
goto free_scan_flter;
}
/* update filter to get scan result with just target BSSID */
if (NULL == scan_filter->BSSIDs.bssid) {
scan_filter->BSSIDs.bssid =
qdf_mem_malloc(sizeof(struct qdf_mac_addr));
if (scan_filter->BSSIDs.bssid == NULL) {
sms_log(mac_ctx, LOGE, FL("malloc failed"));
status = QDF_STATUS_E_NOMEM;
goto free_scan_flter;
}
}
scan_filter->BSSIDs.numOfBSSIDs = 1;
qdf_mem_copy(scan_filter->BSSIDs.bssid[0].bytes,
bssid, sizeof(struct qdf_mac_addr));
status = csr_scan_get_result(mac_ctx, scan_filter, &result_handle);
if (QDF_STATUS_SUCCESS != status) {
sms_log(mac_ctx, LOGE, FL("parse_scan_result failed"));
goto free_scan_flter;
}
bss_list = (tScanResultList *)result_handle;
bss_descp = csr_get_fst_bssdescr_ptr(bss_list);
/*
* bss_descp->length = sizeof(tSirBssDescription) - sizeof(length_field)
* - sizeof(ieFields) + ie_len;
*/
ie_len = bss_descp->length - sizeof(tSirBssDescription)
+ sizeof(bss_descp->length) + sizeof(bss_descp->ieFields);
sms_log(mac_ctx, LOG1, FL("found bss_descriptor ie_len: %d"),
ie_len);
/* include mac header and fixed params along with IEs in frame */
*frame_len = SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET + ie_len;
*frame_buf = qdf_mem_malloc(*frame_len);
if (NULL == *frame_buf) {
sms_log(mac_ctx, LOGE, FL("memory allocation failed"));
status = QDF_STATUS_E_NOMEM;
goto free_scan_flter;
}
sme_prepare_beacon_from_bss_descp(*frame_buf, bss_descp, bssid, ie_len);
free_scan_flter:
/* free scan filter and exit */
if (scan_filter) {
csr_free_scan_filter(mac_ctx, scan_filter);
qdf_mem_free(scan_filter);
}
return QDF_STATUS_SUCCESS;
}

Bestand weergeven

@@ -7416,6 +7416,42 @@ QDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(tpAniSirGlobal pMac,
}
#endif
/**
* csr_get_fst_bssdescr_ptr() - This function returns the pointer to first bss
* description from scan handle
* @result_handle: an object for the result.
*
* Return: first bss descriptor from the scan handle.
*/
tpSirBssDescription csr_get_fst_bssdescr_ptr(tScanResultHandle result_handle)
{
tListElem *first_element = NULL;
tCsrScanResult *scan_result = NULL;
tScanResultList *bss_list = (tScanResultList *)result_handle;
if (NULL == bss_list) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("Empty bss_list"));
return NULL;
}
if (csr_ll_is_list_empty(&bss_list->List, LL_ACCESS_NOLOCK)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("bss_list->List is empty"));
qdf_mem_free(bss_list);
return NULL;
}
first_element = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK);
if (NULL == first_element) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("peer head return NULL"));
return NULL;
}
scan_result = GET_BASE_ADDR(first_element, tCsrScanResult, Link);
return &scan_result->Result.BssDescriptor;
}
/**
* csr_get_bssdescr_from_scan_handle() - This function to extract
* first bss description from scan handle

Bestand weergeven

@@ -1049,6 +1049,9 @@ QDF_STATUS csr_scan_handle_search_for_ssid(tpAniSirGlobal mac,
tSmeCmd *command);
QDF_STATUS csr_scan_handle_search_for_ssid_failure(tpAniSirGlobal mac,
tSmeCmd *command);
tpSirBssDescription csr_get_fst_bssdescr_ptr(tScanResultHandle result_handle);
tSirBssDescription*
csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle,
tSirBssDescription *bss_descr);

Bestand weergeven

@@ -2141,11 +2141,15 @@ typedef struct wma_unit_test_cmd {
* @vdev_id: vdev id
* @bssid: mac address
* @channel: channel
* @frame_len: frame length, includs mac header, fixed params and ies
* @frame_buf: buffer contaning probe response or beacon
*/
struct wma_roam_invoke_cmd {
uint32_t vdev_id;
uint8_t bssid[IEEE80211_ADDR_LEN];
uint32_t channel;
uint32_t frame_len;
uint8_t *frame_buf;
};
/**

Bestand weergeven

@@ -2059,12 +2059,17 @@ void wma_process_roam_invoke(WMA_HANDLE handle,
if (!wma_handle || !wma_handle->wmi_handle) {
WMA_LOGE("%s: WMA is closed, can not send roam invoke",
__func__);
return;
goto free_frame_buf;
}
ch_hz = (A_UINT32)cds_chan_to_freq(roaminvoke->channel);
wmi_unified_roam_invoke_cmd(wma_handle->wmi_handle,
(struct wmi_roam_invoke_cmd *)roaminvoke,
ch_hz);
free_frame_buf:
if (roaminvoke->frame_len) {
qdf_mem_free(roaminvoke->frame_buf);
roaminvoke->frame_buf = NULL;
}
return;
}