diff options
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 284 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 28 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 200 | ||||
| -rw-r--r-- | CORE/SME/inc/csrInternal.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/csrNeighborRoam.h | 5 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 3 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrApiRoam.c | 4 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 75 |
8 files changed, 581 insertions, 19 deletions
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 078aa5d94ca2..fcda50ca04f7 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -1476,6 +1476,283 @@ max_buffer_err: return -EINVAL; } +static int +wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + uint8_t session_id; + struct roam_ext_params roam_params; + uint32_t cmd_type, req_id; + struct nlattr *curr_attr; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX + 1]; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX + 1]; + int rem,i, buf_len; + uint8_t *buf; + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX, + data, data_len, + NULL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + /* Parse and fetch Command Type*/ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("roam cmd type failed")); + goto fail; + } + session_id = pAdapter->sessionId; + vos_mem_set(&roam_params, sizeof(roam_params),0); + cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]); + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + req_id = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]); + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Req Id (%d)"), req_id); + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Cmd Type (%d)"), cmd_type); + switch(cmd_type) { + case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SSID_WHITE_LIST: + /* Parse and fetch number of allowed ssid */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr num of allowed ssid failed")); + goto fail; + } + roam_params.num_ssid_allowed_list = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("Num of Allowed SSID (%d)"), + roam_params.num_ssid_allowed_list); + i = 0; + nla_for_each_nested(curr_attr, + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST], + rem) { + if (nla_parse(tb2, + QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_MAX, + nla_data(curr_attr), nla_len(curr_attr), + NULL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("nla_parse failed")); + goto fail; + } + /* Parse and Fetch allowed SSID list*/ + if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr allowed ssid failed")); + goto fail; + } + buf = nla_data(tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID]); + buf_len = nla_len(tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID]); + nla_strlcpy(roam_params.ssid_allowed_list[i].ssId, + tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID], + buf_len); + roam_params.ssid_allowed_list[i].length = + buf_len - 1; + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("SSID[%d]: %s,length = %d"), i, + roam_params.ssid_allowed_list[i].ssId, + roam_params.ssid_allowed_list[i].length); + i++; + } + sme_update_roam_params(pHddCtx->hHal, session_id, + roam_params, REASON_ROAM_SET_SSID_ALLOWED); + break; + case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_EXTSCAN_ROAM_PARAMS: + /* Parse and fetch 5G Boost Threshold */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("5G boost threshold failed")); + goto fail; + } + roam_params.raise_rssi_thresh_5g = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("5G Boost Threshold (%d)"), + roam_params.raise_rssi_thresh_5g); + /* Parse and fetch 5G Penalty Threshold */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("5G penalty threshold failed")); + goto fail; + } + roam_params.drop_rssi_thresh_5g = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("5G Penalty Threshold (%d)"), + roam_params.drop_rssi_thresh_5g); + /* Parse and fetch 5G Boost Factor */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("5G boost Factor failed")); + goto fail; + } + roam_params.raise_factor_5g = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR]); + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("5G Boost Factor (%d)"), + roam_params.raise_factor_5g); + /* Parse and fetch 5G Penalty factor */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("5G Penalty Factor failed")); + goto fail; + } + roam_params.drop_factor_5g = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("5G Penalty factor (%d)"), + roam_params.drop_factor_5g); + /* Parse and fetch 5G Max Boost */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("5G Max Boost failed")); + goto fail; + } + roam_params.max_raise_rssi_5g = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST]); + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("5G Max Boost (%d)"), + roam_params.max_raise_rssi_5g); + /* Parse and fetch Rssi Diff */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Rssi Diff failed")); + goto fail; + } + roam_params.rssi_diff = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS]); + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("RSSI Diff (%d)"), + roam_params.rssi_diff); + /* Parse and fetch Good Rssi Threshold */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Good Rssi Threshold failed")); + goto fail; + } + roam_params.good_rssi_threshold = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("Good RSSI Threshold (%d)"), + roam_params.good_rssi_threshold); + sme_update_roam_params(pHddCtx->hHal, session_id, + roam_params, + REASON_ROAM_EXT_SCAN_PARAMS_CHANGED); + break; + case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_LAZY_ROAM: + /* Parse and fetch Activate Good Rssi Roam */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Activate Good Rssi Roam failed")); + goto fail; + } + roam_params.good_rssi_roam = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("Activate Good Rssi Roam (%d)"), + roam_params.good_rssi_roam); + sme_update_roam_params(pHddCtx->hHal, session_id, + roam_params, REASON_ROAM_GOOD_RSSI_CHANGED); + break; + case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BSSID_PREFS: + /* Parse and fetch number of preferred BSSID */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr num of preferred bssid failed")); + goto fail; + } + roam_params.num_bssid_favored = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("Num of Preferred BSSID (%d)"), + roam_params.num_bssid_favored); + i = 0; + nla_for_each_nested(curr_attr, + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS], + rem) { + if (nla_parse(tb2, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX, + nla_data(curr_attr), nla_len(curr_attr), + NULL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("nla_parse failed")); + goto fail; + } + /* Parse and fetch MAC address */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr mac address failed")); + goto fail; + } + nla_memcpy(roam_params.bssid_favored[i], + tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID], + sizeof(tSirMacAddr)); + hddLog(VOS_TRACE_LEVEL_DEBUG, MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(roam_params.bssid_favored[i])); + /* Parse and fetch preference factor*/ + if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("BSSID Preference score failed")); + goto fail; + } + roam_params.bssid_favored_factor[i] = nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("BSSID Preference score (%d)"), + roam_params.bssid_favored_factor[i]); + i++; + } + sme_update_roam_params(pHddCtx->hHal, session_id, + roam_params, REASON_ROAM_SET_FAVORED_BSSID); + break; + case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID: + /* Parse and fetch number of blacklist BSSID */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr num of blacklist bssid failed")); + goto fail; + } + roam_params.num_bssid_avoid_list = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID]); + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("Num of blacklist BSSID (%d)"), + roam_params.num_bssid_avoid_list); + i = 0; + nla_for_each_nested(curr_attr, + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS], + rem) { + if (nla_parse(tb2, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX, + nla_data(curr_attr), nla_len(curr_attr), + NULL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("nla_parse failed")); + goto fail; + } + /* Parse and fetch MAC address */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr blacklist addr failed")); + goto fail; + } + nla_memcpy(roam_params.bssid_avoid_list[i], + tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID], + sizeof(tSirMacAddr)); + hddLog(VOS_TRACE_LEVEL_DEBUG, MAC_ADDRESS_STR, + MAC_ADDR_ARRAY( + roam_params.bssid_avoid_list[i])); + i++; + } + sme_update_roam_params(pHddCtx->hHal, session_id, + roam_params, REASON_ROAM_SET_BLACKLIST_BSSID); + break; + } + return 0; +fail: + return -EINVAL; +} #ifdef WLAN_FEATURE_STATS_EXT static int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy, @@ -5923,6 +6200,13 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = (void *)wlan_hdd_cfg80211_wifi_configuration_set }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_set_ext_roam_params + }, }; diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 4d8cd7c9ceb2..aff408675f12 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -3700,6 +3700,30 @@ typedef enum { SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL = 1, SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE = 2 } eSirDFSRoamScanMode; +#define MAX_SSID_ALLOWED_LIST 4 +#define MAX_BSSID_AVOID_LIST 16 +#define MAX_BSSID_FAVORED 16 +struct roam_ext_params { + uint8_t num_bssid_avoid_list; + uint8_t num_ssid_allowed_list; + uint8_t num_bssid_favored; + tSirMacSSid ssid_allowed_list[MAX_SSID_ALLOWED_LIST]; + tSirMacAddr bssid_avoid_list[MAX_BSSID_AVOID_LIST]; + tSirMacAddr bssid_favored[MAX_BSSID_FAVORED]; + uint8_t bssid_favored_factor[MAX_BSSID_FAVORED]; + int raise_rssi_thresh_5g; + int drop_rssi_thresh_5g; + uint8_t raise_rssi_type_5g; + uint8_t raise_factor_5g; + uint8_t drop_rssi_type_5g; + uint8_t drop_factor_5g; + int max_raise_rssi_5g; + int max_drop_rssi_5g; + int good_rssi_threshold; + int rssi_diff; + int good_rssi_roam; + bool is_5g_pref_enabled; +}; typedef struct sSirRoamOffloadScanReq { @@ -3712,7 +3736,7 @@ typedef struct sSirRoamOffloadScanReq tANI_U8 RoamRssiDiff; tANI_U8 ChannelCacheType; tANI_U8 Command; - tANI_U8 StartScanReason; + tANI_U8 reason; tANI_U16 NeighborScanTimerPeriod; tANI_U16 NeighborRoamScanRefreshPeriod; tANI_U16 NeighborScanChannelMinTime; @@ -3759,6 +3783,8 @@ typedef struct sSirRoamOffloadScanReq tANI_U32 R0KH_ID_Length; tANI_U8 RoamKeyMgmtOffloadEnabled; #endif + struct roam_ext_params roam_params; + } tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq; typedef struct sSirRoamOffloadScanRsp diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index a1bafd877439..a58f80764e4e 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -8214,19 +8214,24 @@ error: * Returns : */ VOS_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle, - A_INT32 rssi_thresh, - A_INT32 rssi_thresh_diff, - u_int32_t vdev_id) + tSirRoamOffloadScanReq *roam_req) { VOS_STATUS vos_status = VOS_STATUS_SUCCESS; wmi_buf_t buf = NULL; int status = 0; - int len; + int len, rssi_thresh, rssi_thresh_diff; u_int8_t *buf_ptr; wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; + wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL; + struct roam_ext_params *roam_params; /* Send rssi threshold */ + roam_params = &roam_req->roam_params; + rssi_thresh = roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT; + rssi_thresh_diff = roam_req->OpportunisticScanThresholdDiff; len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); + len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/ + len += sizeof(wmi_roam_scan_extended_threshold_param); buf = wmi_buf_alloc(wma_handle->wmi_handle, len); if (!buf) { WMA_LOGE("%s : wmi_buf_alloc failed", __func__); @@ -8240,10 +8245,39 @@ VOS_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle, WMITLV_GET_STRUCT_TLVLEN( wmi_roam_scan_rssi_threshold_fixed_param)); /* fill in threshold values */ - rssi_threshold_fp->vdev_id = vdev_id; + rssi_threshold_fp->vdev_id = roam_req->sessionId; rssi_threshold_fp->roam_scan_rssi_thresh = rssi_thresh & 0x000000ff; rssi_threshold_fp->roam_rssi_thresh_diff = rssi_thresh_diff & 0x000000ff; - + buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_scan_extended_threshold_param)); + buf_ptr += WMI_TLV_HDR_SIZE; + ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr; + ext_thresholds->boost_threshold_5g = + (roam_params->raise_rssi_thresh_5g - WMA_NOISE_FLOOR_DBM_DEFAULT) & + 0x000000ff; + ext_thresholds->penalty_threshold_5g = + (roam_params->drop_rssi_thresh_5g - WMA_NOISE_FLOOR_DBM_DEFAULT) & + 0x000000ff; + ext_thresholds->boost_algorithm_5g = WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; + ext_thresholds->boost_factor_5g = roam_params->raise_factor_5g; + ext_thresholds->penalty_algorithm_5g = + WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR; + ext_thresholds->penalty_factor_5g = roam_params->drop_factor_5g; + ext_thresholds->max_boost_5g = + (roam_params->max_raise_rssi_5g - WMA_NOISE_FLOOR_DBM_DEFAULT) & + 0x000000ff; + ext_thresholds->max_penalty_5g = + (roam_params->max_drop_rssi_5g - WMA_NOISE_FLOOR_DBM_DEFAULT) & + 0x000000ff; + ext_thresholds->good_rssi_threshold = + (roam_params->good_rssi_threshold - WMA_NOISE_FLOOR_DBM_DEFAULT) & + 0x000000ff; + WMITLV_SET_HDR(&ext_thresholds->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_scan_extended_threshold_param)); status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, WMI_ROAM_SCAN_RSSI_THRESHOLD); if (status != EOK) { @@ -8789,6 +8823,131 @@ error: return vos_status; } +VOS_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle, + tSirRoamOffloadScanReq *roam_req) +{ + wmi_buf_t buf = NULL; + int status = 0, i; + uint32_t len, num_bssid_black_list = 0, num_ssid_white_list = 0, + num_bssid_preferred_list = 0; + uint32_t op_bitmap = 0; + uint8_t *buf_ptr; + wmi_roam_filter_fixed_param *roam_filter; + uint8_t *bssid_src_ptr = NULL; + wmi_mac_addr *bssid_dst_ptr = NULL; + wmi_ssid *ssid_ptr = NULL; + uint32_t *bssid_preferred_factor_ptr = NULL; + struct roam_ext_params *roam_params; + + roam_params = &roam_req->roam_params; + len = sizeof(wmi_roam_filter_fixed_param); + len += WMI_TLV_HDR_SIZE; + switch (roam_req->reason) { + case REASON_ROAM_SET_BLACKLIST_BSSID: + op_bitmap |= 0x1; + num_bssid_black_list = roam_params->num_bssid_avoid_list; + len += num_bssid_black_list * sizeof(wmi_mac_addr); + len += WMI_TLV_HDR_SIZE; + break; + case REASON_ROAM_SET_SSID_ALLOWED: + op_bitmap |= 0x2; + num_ssid_white_list = roam_params->num_ssid_allowed_list; + len += num_ssid_white_list * sizeof(wmi_ssid); + len += WMI_TLV_HDR_SIZE; + break; + case REASON_ROAM_SET_FAVORED_BSSID: + op_bitmap |= 0x4; + num_bssid_preferred_list = roam_params->num_bssid_favored; + len += num_bssid_preferred_list * sizeof(wmi_mac_addr); + len += WMI_TLV_HDR_SIZE; + len += num_bssid_preferred_list * sizeof(A_UINT32); + break; + default: + WMA_LOGD("%s : Roam Filter need not be sent", __func__); + return VOS_STATUS_SUCCESS; + break; + } + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&roam_filter->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param)); + /* fill in fixed values */ + roam_filter->vdev_id = roam_req->sessionId; + roam_filter->flags = 0; + roam_filter->op_bitmap = op_bitmap; + roam_filter->num_bssid_black_list = num_bssid_black_list; + roam_filter->num_ssid_white_list = num_ssid_white_list; + roam_filter->num_bssid_preferred_list = num_bssid_preferred_list; + buf_ptr += sizeof(wmi_roam_filter_fixed_param); + + WMITLV_SET_HDR((buf_ptr), + WMITLV_TAG_ARRAY_FIXED_STRUC, + (num_bssid_black_list * sizeof(wmi_mac_addr))); + bssid_src_ptr = (uint8_t *)&roam_params->bssid_avoid_list; + bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); + for(i=0; i<num_bssid_black_list; i++) { + WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr); + bssid_src_ptr += sizeof(ATH_MAC_LEN); + bssid_dst_ptr++; + } + buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid_black_list * sizeof(wmi_mac_addr)); + WMITLV_SET_HDR((buf_ptr), + WMITLV_TAG_ARRAY_FIXED_STRUC, + (num_ssid_white_list * sizeof(wmi_ssid))); + ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); + for(i=0; i<num_ssid_white_list; i++) { + memcpy(&ssid_ptr->ssid, &roam_params->ssid_allowed_list[i].ssId, + roam_params->ssid_allowed_list[i].length); + ssid_ptr->ssid_len = roam_params->ssid_allowed_list[i].length; + WMA_LOGD("%s: Passing SSID of length=%d", __func__,ssid_ptr->ssid_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + (uint8_t *)ssid_ptr->ssid, + ssid_ptr->ssid_len); + ssid_ptr++; + } + buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid_white_list * sizeof(wmi_ssid)); + WMITLV_SET_HDR((buf_ptr), + WMITLV_TAG_ARRAY_FIXED_STRUC, + (num_bssid_preferred_list * sizeof(wmi_mac_addr))); + bssid_src_ptr = (uint8_t *)&roam_params->bssid_favored; + bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); + for(i=0; i<num_bssid_preferred_list; i++) { + WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, + (wmi_mac_addr *)bssid_dst_ptr); + bssid_src_ptr += sizeof(ATH_MAC_LEN); + bssid_dst_ptr++; + } + buf_ptr += WMI_TLV_HDR_SIZE + + (num_bssid_preferred_list * sizeof(wmi_mac_addr)); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (num_bssid_preferred_list * sizeof(uint32_t))); + bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); + for (i=0; i<num_bssid_preferred_list; i++) { + *bssid_preferred_factor_ptr = roam_params->bssid_favored_factor[i]; + bssid_preferred_factor_ptr++; + } + buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid_preferred_list * sizeof(uint32_t)); + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_FILTER_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_FILTER_CMDID returned Error %d", + status); + goto error; + } + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; +} + VOS_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle, A_INT32 first_bcnt, A_UINT32 final_bcnt, @@ -8883,7 +9042,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, struct wma_txrx_node *intr = NULL; WMA_LOGI("%s: command 0x%x, reason %d", __func__, roam_req->Command, - roam_req->StartScanReason); + roam_req->reason); if (NULL == pMac) { @@ -8914,9 +9073,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, wma_handle->suitable_ap_hb_failure = FALSE; vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle, - (roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT), - roam_req->OpportunisticScanThresholdDiff, - roam_req->sessionId); + roam_req); if (vos_status != VOS_STATUS_SUCCESS) { break; } @@ -8984,6 +9141,14 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, roam_req, mode, roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + vos_status = wma_roam_scan_filter(wma_handle, roam_req); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Sending start for roam scan filter failed"); + break; + } break; case ROAM_SCAN_OFFLOAD_STOP: @@ -8999,7 +9164,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, roam_req->sessionId); } - if (roam_req->StartScanReason == REASON_OS_REQUESTED_ROAMING_NOW) { + if (roam_req->reason == REASON_OS_REQUESTED_ROAMING_NOW) { vos_msg_t vosMsg; tSirRoamOffloadScanRsp *scan_offload_rsp; scan_offload_rsp = vos_mem_malloc(sizeof(*scan_offload_rsp)); @@ -9010,7 +9175,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, } vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP; scan_offload_rsp->sessionId = roam_req->sessionId; - scan_offload_rsp->reason = roam_req->StartScanReason; + scan_offload_rsp->reason = roam_req->reason; vosMsg.bodyptr = scan_offload_rsp; /* * Since REASSOC request is processed in Roam_Scan_Offload_Rsp @@ -9042,7 +9207,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, * and WMI_ROAM_REASON_SUITABLE_AP event was received earlier, * now it is time to call it heartbeat failure. */ - if ((roam_req->StartScanReason == REASON_PREAUTH_FAILED_FOR_ALL) + if ((roam_req->reason == REASON_PREAUTH_FAILED_FOR_ALL) && wma_handle->suitable_ap_hb_failure) { WMA_LOGE("%s: Sending heartbeat failure after preauth failures", __func__); @@ -9073,6 +9238,11 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, if (vos_status != VOS_STATUS_SUCCESS) { break; } + vos_status = wma_roam_scan_filter(wma_handle, roam_req); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Sending update for roam scan filter failed"); + break; + } /* * Runtime (after association) changes to rssi thresholds and other parameters. @@ -9087,9 +9257,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, } vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle, - (roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT), - roam_req->OpportunisticScanThresholdDiff, - roam_req->sessionId); + roam_req); if (vos_status != VOS_STATUS_SUCCESS) { break; } diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h index a9f1619410b3..34fba0eab423 100644 --- a/CORE/SME/inc/csrInternal.h +++ b/CORE/SME/inc/csrInternal.h @@ -675,6 +675,7 @@ typedef struct tagCsrConfig v_U8_t conc_custom_rule1; v_U8_t conc_custom_rule2; v_U8_t is_sta_connection_in_5gz_enabled; + struct roam_ext_params roam_params; }tCsrConfig; typedef struct tagCsrChannelPowerInfo diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h index ed999d820a49..c28b86ca7337 100644 --- a/CORE/SME/inc/csrNeighborRoam.h +++ b/CORE/SME/inc/csrNeighborRoam.h @@ -323,6 +323,11 @@ VOS_STATUS csrNeighborRoamMergeChannelLists(tpAniSirGlobal pMac, #define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED 22 #define REASON_ROAM_DFS_SCAN_MODE_CHANGED 23 #define REASON_ROAM_ABORT_ROAM_SCAN 24 +#define REASON_ROAM_EXT_SCAN_PARAMS_CHANGED 25 +#define REASON_ROAM_SET_SSID_ALLOWED 26 +#define REASON_ROAM_SET_FAVORED_BSSID 27 +#define REASON_ROAM_GOOD_RSSI_CHANGED 28 +#define REASON_ROAM_SET_BLACKLIST_BSSID 29 eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, tANI_U8 command, tANI_U8 reason); eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 6dba4a5c1120..ca5fb7080066 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -378,7 +378,8 @@ void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode); eHalStatus sme_CloseSession(tHalHandle hHal, tANI_U8 sessionId, csrRoamSessionCloseCallback callback, void *pContext); - +eHalStatus sme_update_roam_params(tHalHandle hHal, uint8_t session_id, + struct roam_ext_params roam_params_src, int update_param); /*-------------------------------------------------------------------------- diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 80b46879179f..35bd55933fc3 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -16681,7 +16681,7 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, pRequestBuf->RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff; pRequestBuf->Command = command; - pRequestBuf->StartScanReason = reason; + pRequestBuf->reason = reason; pRequestBuf->NeighborScanTimerPeriod = pNeighborRoamInfo->cfgParams.neighborScanPeriod; pRequestBuf->NeighborRoamScanRefreshPeriod = @@ -16900,6 +16900,8 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, csrRoamOffload(pMac, pRequestBuf, pSession); } #endif + vos_mem_copy(&pRequestBuf->roam_params, &pMac->roam.configParam.roam_params, + sizeof(pRequestBuf->roam_params)); msg.type = WDA_ROAM_SCAN_OFFLOAD_REQ; msg.reserved = 0; msg.bodyptr = pRequestBuf; diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 895434f9a1dd..c01dfe364836 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -1676,6 +1676,81 @@ eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) return status; } +/** + * sme_update_roam_params - Store/Update the roaming params + * @hHal Handle for Hal layer + * @session_id SME Session ID + * @roam_params_src The source buffer to copy + * @update_param Type of parameter to be updated + * + * Return: Return the status of the updation. + */ +eHalStatus sme_update_roam_params(tHalHandle hHal, + uint8_t session_id, struct roam_ext_params roam_params_src, + int update_param) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + struct roam_ext_params *roam_params_dst; + uint8_t i; + + roam_params_dst = &pMac->roam.configParam.roam_params; + switch(update_param) { + case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED: + roam_params_dst->raise_rssi_thresh_5g = + roam_params_src.raise_rssi_thresh_5g; + roam_params_dst->drop_rssi_thresh_5g = + roam_params_src.drop_rssi_thresh_5g; + roam_params_dst->raise_factor_5g= + roam_params_src.raise_factor_5g; + roam_params_dst->drop_factor_5g = + roam_params_src.drop_factor_5g; + roam_params_dst->max_drop_rssi_5g= + roam_params_src.max_drop_rssi_5g; + roam_params_dst->is_5g_pref_enabled = true; + break; + case REASON_ROAM_SET_SSID_ALLOWED: + vos_mem_set(&roam_params_dst->ssid_allowed_list, 0, + sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST); + roam_params_dst->num_ssid_allowed_list= + roam_params_src.num_ssid_allowed_list; + for (i=0; i<roam_params_dst->num_ssid_allowed_list; i++) { + roam_params_dst->ssid_allowed_list[i].length = + roam_params_src.ssid_allowed_list[i].length; + vos_mem_copy(roam_params_dst->ssid_allowed_list[i].ssId, + roam_params_src.ssid_allowed_list[i].ssId, + roam_params_dst->ssid_allowed_list[i].length); + } + break; + case REASON_ROAM_SET_FAVORED_BSSID: + vos_mem_set(&roam_params_dst->bssid_favored, 0, + sizeof(tSirMacAddr) * MAX_BSSID_FAVORED); + roam_params_dst->num_bssid_favored= + roam_params_src.num_bssid_favored; + for (i=0; i<roam_params_dst->num_bssid_favored; i++) { + vos_mem_copy(&roam_params_dst->bssid_favored[i], + &roam_params_src.bssid_favored[i], + sizeof(tSirMacAddr)); + roam_params_dst->bssid_favored_factor[i] = + roam_params_src.bssid_favored_factor[i]; + } + break; + case REASON_ROAM_SET_BLACKLIST_BSSID: + vos_mem_set(&roam_params_dst->bssid_avoid_list, 0, + sizeof(tSirMacAddr) * MAX_BSSID_AVOID_LIST); + roam_params_dst->num_bssid_avoid_list = + roam_params_src.num_bssid_avoid_list; + for (i=0; i<roam_params_dst->num_bssid_avoid_list; i++) { + vos_mem_copy(&roam_params_dst->bssid_avoid_list[i], + &roam_params_src.bssid_avoid_list[i], + sizeof(tSirMacAddr)); + } + default: + break; + } + csrRoamOffloadScan(pMac, session_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + update_param); + return 0; +} #ifdef WLAN_FEATURE_GTK_OFFLOAD void sme_ProcessGetGtkInfoRsp( tHalHandle hHal, tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) |
