diff options
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 217 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 14 |
2 files changed, 129 insertions, 102 deletions
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 521f6e889244..d1886bf69d4a 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -6879,6 +6879,11 @@ iw_get_softap_linkspeed(struct net_device *dev, struct iw_request_info *info, return ret; } +struct peer_rssi_priv { + eHalStatus status; + struct sir_peer_sta_info peer_sta_info; +}; + /** * hdd_get_rssi_cb() - get station's rssi callback * @sta_rssi: pointer of peer information @@ -6890,83 +6895,48 @@ iw_get_softap_linkspeed(struct net_device *dev, struct iw_request_info *info, */ void hdd_get_rssi_cb(struct sir_peer_info_resp *sta_rssi, void *context) { - struct statsContext *get_rssi_context; + struct hdd_request *request; + struct peer_rssi_priv *priv; struct sir_peer_info *rssi_info; uint8_t peer_num; - int i; - int buf = 0; - int length = 0; - char *rssi_info_output; - union iwreq_data *wrqu; - - if ((NULL == sta_rssi) || (NULL == context)) { + request = hdd_request_get(context); + if (!request) { hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Bad param, sta_rssi [%pK] context [%pK]", - __func__, sta_rssi, context); + "Obsolete request %pK", context); return; } + priv = hdd_request_priv(request); - spin_lock(&hdd_context_lock); - /* - * there is a race condition that exists between this callback - * function and the caller since the caller could time out either - * before or while this code is executing. we use a spinlock to - * serialize these actions - */ - get_rssi_context = context; - if (PEER_INFO_CONTEXT_MAGIC != - get_rssi_context->magic) { + if (!sta_rssi) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, sta_rssi [%pK] context [%pK]", + __func__, sta_rssi, context); + priv->status = eHAL_STATUS_INVALID_PARAMETER; + hdd_request_complete(request); + hdd_request_put(request); - /* - * the caller presumably timed out so there is nothing - * we can do - */ - spin_unlock(&hdd_context_lock); - hddLog(VOS_TRACE_LEVEL_WARN, - "%s: Invalid context, magic [%08x]", - __func__, - get_rssi_context->magic); return; } - rssi_info_output = get_rssi_context->extra; - wrqu = get_rssi_context->wrqu; peer_num = sta_rssi->count; rssi_info = sta_rssi->info; - get_rssi_context->magic = 0; - - hddLog(LOG1, "%s : %d peers", __func__, peer_num); + hddLog(VOS_TRACE_LEVEL_INFO, + "%d peers", peer_num); - /* - * The iwpriv tool default print is before mac addr and rssi. - * Add '\n' before first rssi item to align the frist rssi item - * with others - * - * wlan getRSSI: - * [macaddr1] [rssi1] - * [macaddr2] [rssi2] - * [macaddr3] [rssi3] - */ - length = scnprintf((rssi_info_output), WE_MAX_STR_LEN, "\n"); - for (i = 0; i < peer_num; i++) { - buf = scnprintf - ( - (rssi_info_output + length), WE_MAX_STR_LEN - length, - "[%pM] [%d]\n", - rssi_info[i].peer_macaddr, - rssi_info[i].rssi - ); - length += buf; + if (peer_num > MAX_PEER_STA) { + hddLog(VOS_TRACE_LEVEL_WARN, + "Exceed max peer sta to handle one time %d", peer_num); + peer_num = MAX_PEER_STA; } - wrqu->data.length = length + 1; - - /* notify the caller */ - complete(&get_rssi_context->completion); + vos_mem_copy(priv->peer_sta_info.info, rssi_info, + peer_num * sizeof(*rssi_info)); + priv->peer_sta_info.sta_num = peer_num; + priv->status = eHAL_STATUS_SUCCESS; + hdd_request_complete(request); + hdd_request_put(request); - /* serialization is complete */ - spin_unlock(&hdd_context_lock); } /** @@ -6981,64 +6951,69 @@ void hdd_get_rssi_cb(struct sir_peer_info_resp *sta_rssi, void *context) * Return: 0 on success, otherwise error value */ static int wlan_hdd_get_peer_rssi(hdd_adapter_t *adapter, - v_MACADDR_t macaddress, - char *extra, - union iwreq_data *wrqu) + v_MACADDR_t macaddress, + struct sir_peer_sta_info *peer_sta_info) { eHalStatus hstatus; + void *cookie; int ret; - struct statsContext context; struct sir_peer_info_req rssi_req; + struct hdd_request *request; + struct peer_rssi_priv *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; - if (NULL == adapter) { - hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", - __func__); + if (!adapter || !peer_sta_info) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "adapter [%pK], peer_sta_info[%pK]", + adapter, peer_sta_info); return -EFAULT; } - init_completion(&context.completion); - context.magic = PEER_INFO_CONTEXT_MAGIC; - context.extra = extra; - context.wrqu = wrqu; + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Request allocation failure"); + return -ENOMEM; + } + + cookie = hdd_request_cookie(request); + priv = hdd_request_priv(request); + priv->status = eHAL_STATUS_FAILURE; vos_mem_copy(&(rssi_req.peer_macaddr), &macaddress, VOS_MAC_ADDR_SIZE); rssi_req.sessionid = adapter->sessionId; + hstatus = sme_get_peer_info(WLAN_HDD_GET_HAL_CTX(adapter), - rssi_req, - &context, - hdd_get_rssi_cb); + rssi_req, + cookie, + hdd_get_rssi_cb); if (eHAL_STATUS_SUCCESS != hstatus) { hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Unable to retrieve statistics for rssi", - __func__); + "%s: Unable to retrieve statistics for rssi", + __func__); ret = -EFAULT; } else { - if (!wait_for_completion_timeout(&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS))) { + ret = hdd_request_wait_for_response(request); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "SME timed out while retrieving rssi"); + ret = -EFAULT; + } else if (priv->status != eHAL_STATUS_SUCCESS) { hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: SME timed out while retrieving rssi", - __func__); + "request failed %d", priv->status); ret = -EFAULT; - } else + } else { + *peer_sta_info = priv->peer_sta_info; ret = 0; + } } - /* - * either we never sent a request, we sent a request and received a - * response or we sent a request and timed out. if we never sent a - * request or if we sent a request and got a response, we want to - * clear the magic out of paranoia. if we timed out there is a - * race condition such that the callback function could be - * executing at the same time we are. of primary concern is if the - * callback function had already verified the "magic" but had not - * yet set the completion variable when a timeout occurred. we - * serialize these activities by invalidating the magic while - * holding a shared spinlock which will cause us to block if the - * callback is currently executing - */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + + hdd_request_put(request); + return ret; } @@ -7064,6 +7039,12 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, v_MACADDR_t macaddress = VOS_MAC_ADDR_BROADCAST_INITIALIZER; VOS_STATUS status = VOS_STATUS_E_FAILURE; int ret; + char *rssi_info_output = extra; + struct sir_peer_sta_info peer_sta_info; + struct sir_peer_info *rssi_info; + int i; + int buf; + int length; ENTER(); @@ -7073,7 +7054,7 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, return ret; hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", - __func__, wrqu->data.length); + __func__, wrqu->data.length); if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) { @@ -7081,24 +7062,56 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, wrqu->data.pointer, MAC_ADDRESS_STR_LEN - 1)) { hddLog(LOG1, "%s: failed to copy data to user buffer", - __func__); + __func__); return -EFAULT; } macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0'; hddLog(LOG1, "%s, %s", - __func__, macaddrarray); + __func__, macaddrarray); status = hdd_string_to_hex(macaddrarray, MAC_ADDRESS_STR_LEN, macaddress.bytes ); if (!VOS_IS_STATUS_SUCCESS(status)) { hddLog(VOS_TRACE_LEVEL_ERROR, - FL("String to Hex conversion Failed")); + FL("String to Hex conversion Failed")); } } - return wlan_hdd_get_peer_rssi(adapter, macaddress, extra, wrqu); + vos_mem_zero(&peer_sta_info, sizeof(peer_sta_info)); + ret = wlan_hdd_get_peer_rssi(adapter, macaddress, &peer_sta_info); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Unable to retrieve peer rssi: %d", ret); + return ret; + } + + /* + * The iwpriv tool default print is before mac addr and rssi. + * Add '\n' before first rssi item to align the frist rssi item + * with others + * + * wlan getRSSI: + * [macaddr1] [rssi1] + * [macaddr2] [rssi2] + * [macaddr3] [rssi3] + */ + length = scnprintf((rssi_info_output), WE_MAX_STR_LEN, "\n"); + rssi_info = &peer_sta_info.info[0]; + for (i = 0; i < peer_sta_info.sta_num; i++) { + buf = scnprintf((rssi_info_output + length), + WE_MAX_STR_LEN - length, + "[%pM] [%d]\n", + rssi_info[i].peer_macaddr, + rssi_info[i].rssi); + length += buf; + } + wrqu->data.length = length + 1; + + EXIT(); + + return 0; } /** diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index fbfdcf4cb1ad..24564ef25c84 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -111,6 +111,9 @@ typedef tANI_U8 tSirVersionString[SIR_VERSION_STRING_LEN]; /* Cache ID length */ #define CACHE_ID_LEN 2 +/* Maximum peer station number query one time */ +#define MAX_PEER_STA 12 + #ifdef FEATURE_WLAN_EXTSCAN #define WLAN_EXTSCAN_MAX_CHANNELS 36 @@ -4941,6 +4944,17 @@ struct sir_peer_info_resp { }; /** + * @sta_num: number of peer station which has valid info + * @info: peer information + * + * all SAP peer station's information retrieved + */ +struct sir_peer_sta_info { + uint8_t sta_num; + struct sir_peer_info info[MAX_PEER_STA]; +}; + +/** * struct sir_peer_info_ext_req - peer info request struct * @peer_macaddr: MAC address * @sessionId: vdev id |
