Пример #1
0
iscan_buf_t *dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf)
{
	iscan_buf_t *iscanbuf_alloc = 0;
	iscan_buf_t *iscanbuf_head;

	dhd_iscan_lock();

	iscanbuf_alloc = kmalloc(sizeof(iscan_buf_t), GFP_ATOMIC);
	if (iscanbuf_alloc == NULL)
		goto fail;

	iscanbuf_alloc->next = NULL;
	iscanbuf_head = *iscanbuf;

	DHD_ISCAN(("%s: addr of allocated node = 0x%X"
		   "addr of iscanbuf_head = 0x%X dhd = 0x%X\n",
		   __func__, iscanbuf_alloc, iscanbuf_head, dhd));

	if (iscanbuf_head == NULL) {
		*iscanbuf = iscanbuf_alloc;
		DHD_ISCAN(("%s: Head is allocated\n", __func__));
		goto fail;
	}

	while (iscanbuf_head->next)
		iscanbuf_head = iscanbuf_head->next;

	iscanbuf_head->next = iscanbuf_alloc;

fail:
	dhd_iscan_unlock();
	return iscanbuf_alloc;
}
Пример #2
0
iscan_buf_t *
dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf)
{
	iscan_buf_t *iscanbuf_alloc = 0;
	iscan_buf_t *iscanbuf_head;

	DHD_TRACE(("%s: Entered\n", __FUNCTION__));
	dhd_iscan_lock();

	iscanbuf_alloc = (iscan_buf_t*)MALLOC(dhd->osh, sizeof(iscan_buf_t));
	if (iscanbuf_alloc == NULL)
		goto fail;

	iscanbuf_alloc->next = NULL;
	iscanbuf_head = *iscanbuf;

	DHD_ISCAN(("%s: addr of allocated node = 0x%X"
		   "addr of iscanbuf_head = 0x%X dhd = 0x%X\n",
		   __FUNCTION__, iscanbuf_alloc, iscanbuf_head, dhd));

	if (iscanbuf_head == NULL) {
		*iscanbuf = iscanbuf_alloc;
		DHD_ISCAN(("%s: Head is allocated\n", __FUNCTION__));
		goto fail;
	}

	while (iscanbuf_head->next)
		iscanbuf_head = iscanbuf_head->next;

	iscanbuf_head->next = iscanbuf_alloc;

fail:
	dhd_iscan_unlock();
	return iscanbuf_alloc;
}
Пример #3
0
static int
dhd_iscan_get_partial_result(void *dhdp, uint *scan_count)
{
	wl_iscan_results_t *list_buf;
	wl_iscan_results_t list;
	wl_scan_results_t *results;
	iscan_buf_t *iscan_cur;
	int status = -1;
	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
	int rc;

	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

	iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain);
	if (!iscan_cur) {
		DHD_ERROR(("%s: Failed to allocate node\n", __FUNCTION__));
		dhd_iscan_free_buf(dhdp, 0);
		dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT);
		dhd_ind_scan_confirm(dhdp, FALSE);
		goto fail;
	}

	dhd_iscan_lock();

	memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
	list_buf = (wl_iscan_results_t*)iscan_cur->iscan_buf;
	results = &list_buf->results;
	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
	results->version = 0;
	results->count = 0;

	memset(&list, 0, sizeof(list));
	list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN);
	bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE,
		iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN);
	rc = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iscan_cur->iscan_buf,
	                      WLC_IW_ISCAN_MAXLEN, FALSE, 0);

	results->buflen = dtoh32(results->buflen);
	results->version = dtoh32(results->version);
	*scan_count = results->count = dtoh32(results->count);
	status = dtoh32(list_buf->status);
	DHD_TRACE(("%s: Got %d resuls\n", __FUNCTION__, results->count));

	dhd_iscan_unlock();

	if (!(*scan_count)) {
		dhd_iscan_free_buf(dhdp, iscan_cur);
	}
fail:
	return status;
}
Пример #4
0
int dhd_iscan_remove_duplicates(void *dhdp, iscan_buf_t *iscan_cur)
{
	int i = 0;
	wl_iscan_results_t *list;
	wl_scan_results_t *results;
	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;

	dhd_iscan_lock();

	DHD_ISCAN(("%s: Scan cache before delete\n", __func__));
	dhd_iscan_print_cache(iscan_cur);

	if (!iscan_cur)
		goto done;

	list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
	if (!list)
		goto done;

	results = (wl_scan_results_t *)&list->results;
	if (!results)
		goto done;

	if (results->version != WL_BSS_INFO_VERSION) {
		DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n",
			   __func__, results->version));
		goto done;
	}

	bi = results->bss_info;
	for (i = 0; i < results->count; i++) {
		if (!bi)
			break;

		DHD_ISCAN(("%s: Find dups for BSS[%2.2d] %X:%X:%X:%X:%X:%X\n",
			   __func__, i, bi->BSSID.octet[0],
			   bi->BSSID.octet[1], bi->BSSID.octet[2],
			   bi->BSSID.octet[3], bi->BSSID.octet[4],
			   bi->BSSID.octet[5]));

		dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur);

		bi = (wl_bss_info_t *)((unsigned long)bi + bi->length);
	}

done:
	DHD_ISCAN(("%s: Scan cache after delete\n", __func__));
	dhd_iscan_print_cache(iscan_cur);
	dhd_iscan_unlock();
	return 0;
}
Пример #5
0
static int dhd_iscan_get_partial_result(void *dhdp, uint *scan_count)
{
	wl_iscan_results_t *list_buf;
	wl_iscan_results_t list;
	wl_scan_results_t *results;
	iscan_buf_t *iscan_cur;
	int status = -1;
	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
	int rc;

	iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain);
	if (!iscan_cur) {
		DHD_ERROR(("%s: Failed to allocate node\n", __func__));
		dhd_iscan_free_buf(dhdp, 0);
		dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT);
		goto fail;
	}

	dhd_iscan_lock();

	memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
	list_buf = (wl_iscan_results_t *) iscan_cur->iscan_buf;
	results = &list_buf->results;
	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
	results->version = 0;
	results->count = 0;

	memset(&list, 0, sizeof(list));
	list.results.buflen = WLC_IW_ISCAN_MAXLEN;
	bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE,
		    iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN);
	rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf,
			  WLC_IW_ISCAN_MAXLEN);

	results->buflen = results->buflen;
	results->version = results->version;
	*scan_count = results->count = results->count;
	status = list_buf->status;

	dhd_iscan_unlock();

	if (!(*scan_count))
		dhd_iscan_free_buf(dhdp, iscan_cur);
	else
		dhd_iscan_remove_duplicates(dhdp, iscan_cur);

fail:
	return status;
}
Пример #6
0
/*
* print scan cache
* print partial iscan_skip list differently
*/
int dhd_iscan_print_cache(iscan_buf_t *iscan_skip)
{
	int i = 0, l = 0;
	iscan_buf_t *iscan_cur;
	wl_iscan_results_t *list;
	wl_scan_results_t *results;
	wl_bss_info_t UNALIGNED *bi;

	dhd_iscan_lock();

	iscan_cur = dhd_iscan_result_buf();

	while (iscan_cur) {
		list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
		if (!list)
			break;

		results = (wl_scan_results_t *)&list->results;
		if (!results)
			break;

		if (results->version != WL_BSS_INFO_VERSION) {
			DHD_ISCAN(("%s: results->version %d != "
				"WL_BSS_INFO_VERSION\n",
				__func__, results->version));
			goto done;
		}

		bi = results->bss_info;
		for (i = 0; i < results->count; i++) {
			if (!bi)
				break;

			DHD_ISCAN(("%s[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n",
				   iscan_cur != iscan_skip ? "BSS" : "bss", l,
				   i, bi->BSSID.octet[0], bi->BSSID.octet[1],
				   bi->BSSID.octet[2], bi->BSSID.octet[3],
				   bi->BSSID.octet[4], bi->BSSID.octet[5]));

			bi = (wl_bss_info_t *)((unsigned long)bi + bi->length);
		}
		iscan_cur = iscan_cur->next;
		l++;
	}

done:
	dhd_iscan_unlock();
	return 0;
}
Пример #7
0
void
dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
{
	iscan_buf_t *iscanbuf_free = 0;
	iscan_buf_t *iscanbuf_prv = 0;
	iscan_buf_t *iscanbuf_cur;
	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
	DHD_TRACE(("%s: Entered\n", __FUNCTION__));

	dhd_iscan_lock();

	iscanbuf_cur = iscan_chain;

	/* If iscan_delete is null then delete the entire 
	 * chain or else delete specific one provided
	 */
	if (!iscan_delete) {
		while (iscanbuf_cur) {
			iscanbuf_free = iscanbuf_cur;
			iscanbuf_cur = iscanbuf_cur->next;
			iscanbuf_free->next = 0;
			MFREE(dhd->osh, iscanbuf_free, sizeof(iscan_buf_t));
		}
		iscan_chain = 0;
	} else {
		while (iscanbuf_cur) {
			if (iscanbuf_cur == iscan_delete)
				break;
			iscanbuf_prv = iscanbuf_cur;
			iscanbuf_cur = iscanbuf_cur->next;
		}
		if (iscanbuf_prv)
			iscanbuf_prv->next = iscan_delete->next;

		iscan_delete->next = 0;
		MFREE(dhd->osh, iscan_delete, sizeof(iscan_buf_t));

		if (!iscanbuf_prv)
			iscan_chain = 0;
	}
	dhd_iscan_unlock();
}
Пример #8
0
void dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
{
	iscan_buf_t *iscanbuf_free = 0;
	iscan_buf_t *iscanbuf_prv = 0;
	iscan_buf_t *iscanbuf_cur = iscan_chain;
	dhd_pub_t *dhd = dhd_bus_pub(dhdp);

	dhd_iscan_lock();
	/* If iscan_delete is null then delete the entire
	 * chain or else delete specific one provided
	 */
	if (!iscan_delete) {
		while (iscanbuf_cur) {
			iscanbuf_free = iscanbuf_cur;
			iscanbuf_cur = iscanbuf_cur->next;
			iscanbuf_free->next = 0;
			kfree(iscanbuf_free);
		}
		iscan_chain = 0;
	} else {
		while (iscanbuf_cur) {
			if (iscanbuf_cur == iscan_delete)
				break;
			iscanbuf_prv = iscanbuf_cur;
			iscanbuf_cur = iscanbuf_cur->next;
		}
		if (iscanbuf_prv)
			iscanbuf_prv->next = iscan_delete->next;

		iscan_delete->next = 0;
		kfree(iscan_delete);

		if (!iscanbuf_prv)
			iscan_chain = 0;
	}
	dhd_iscan_unlock();
}
Пример #9
0
/*
* delete disappeared AP from specific scan cache
*/
int
dhd_iscan_delete_bss(/* TBD void *dhdp, */ void *addr)
{
	int i = 0, j = 0, l = 0;
	iscan_buf_t *iscan_cur;
	wl_iscan_results_t *list;
	wl_scan_results_t *results;
	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;

	uchar *s_addr = addr;
	DHD_TRACE(("%s: Entered\n", __FUNCTION__));

	dhd_iscan_lock();
	DHD_TRACE(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n",
	__FUNCTION__, s_addr[0], s_addr[1], s_addr[2],
	s_addr[3], s_addr[4], s_addr[5]));

	DHD_TRACE(("%s: Scan cache before delete\n",
	__FUNCTION__));

	iscan_cur = dhd_iscan_result_buf();

	while (iscan_cur) {
			list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
			if (!list)
				break;

			results = (wl_scan_results_t *)&list->results;
			if (!results)
				break;

			if (results->version != WL_BSS_INFO_VERSION) {
			DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n",
				__FUNCTION__, results->version));
				goto done;
			}

			bi = results->bss_info;
			for (i = 0; i < results->count; i++) {
				if (!bi)
					break;

				if (!memcmp(bi->BSSID.octet, addr, ETHER_ADDR_LEN)) {
					DHD_TRACE(("%s: Del BSS[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n",
					__FUNCTION__, l, i, bi->BSSID.octet[0], bi->BSSID.octet[1],
					bi->BSSID.octet[2], bi->BSSID.octet[3], bi->BSSID.octet[4],
					bi->BSSID.octet[5]));

					bi_new = bi;
					bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length));


					for (j = i; j < results->count; j++) {
					DHD_TRACE(("%s: Moved up BSS[%2.2d:%2.2d]"
					" %X:%X:%X:%X:%X:%X\n",
					__FUNCTION__, l, j, bi->BSSID.octet[0], bi->BSSID.octet[1],
					bi->BSSID.octet[2], bi->BSSID.octet[3], bi->BSSID.octet[4],
					bi->BSSID.octet[5]));

					bi_next = (wl_bss_info_t *)((uintptr)bi +
						dtoh32(bi->length));
							bcopy(bi, bi_new, dtoh32(bi->length));
					bi_new = (wl_bss_info_t *)((uintptr)bi_new +
						dtoh32(bi_new->length));
							bi = bi_next;
						}
				results->count--;
					if (results->count == 0) {
						/* Prune now empty partial scan list */
						goto done;
					}
					break;
				}

				bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length));
			}
		iscan_cur = iscan_cur->next;
		l++;
	}

done:
	DHD_TRACE(("%s: Scan cache after delete\n",
		__FUNCTION__));
	dhd_iscan_unlock();
	return 0;
}
Пример #10
0
/*
* delete disappeared AP from specific scan cache but skip partial
* list in iscan_skip
*/
int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip)
{
	int i = 0, j = 0, l = 0;
	iscan_buf_t *iscan_cur;
	wl_iscan_results_t *list;
	wl_scan_results_t *results;
	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;

	unsigned char *s_addr = addr;

	dhd_iscan_lock();
	DHD_ISCAN(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n",
		   __func__, s_addr[0], s_addr[1], s_addr[2],
		   s_addr[3], s_addr[4], s_addr[5]));

	iscan_cur = dhd_iscan_result_buf();

	while (iscan_cur) {
		if (iscan_cur != iscan_skip) {
			list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
			if (!list)
				break;

			results = (wl_scan_results_t *)&list->results;
			if (!results)
				break;

			if (results->version != WL_BSS_INFO_VERSION) {
				DHD_ERROR(("%s: results->version %d != "
					"WL_BSS_INFO_VERSION\n",
					__func__, results->version));
				goto done;
			}

			bi = results->bss_info;
			for (i = 0; i < results->count; i++) {
				if (!bi)
					break;

				if (!memcmp
				    (bi->BSSID.octet, addr, ETH_ALEN)) {
					DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] "
					"%X:%X:%X:%X:%X:%X\n",
					__func__, l, i, bi->BSSID.octet[0],
					bi->BSSID.octet[1], bi->BSSID.octet[2],
					bi->BSSID.octet[3], bi->BSSID.octet[4],
					bi->BSSID.octet[5]));

					bi_new = bi;
					bi = (wl_bss_info_t *)((unsigned long)
							       bi + bi->length);
/*
			if(bi && bi_new) {
				memcpy(bi_new, bi, results->buflen -
				bi_new->length);
				results->buflen -= bi_new->length;
			}
*/
					results->buflen -= bi_new->length;
					results->count--;

					for (j = i; j < results->count; j++) {
						if (bi && bi_new) {
							DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]" "%X:%X:%X:%X:%X:%X\n",
							__func__, l, j,
							bi->BSSID.octet[0],
							bi->BSSID.octet[1],
							bi->BSSID.octet[2],
							bi->BSSID.octet[3],
							bi->BSSID.octet[4],
							bi->BSSID.octet[5]));

							bi_next =
							    (wl_bss_info_t *)((unsigned long)bi +
								 bi->length);
							memcpy(bi_new, bi,
							      bi->length);
							bi_new =
							    (wl_bss_info_t *)((unsigned long)bi_new +
								 bi_new->
								  length);
							bi = bi_next;
						}
					}

					if (results->count == 0) {
						/* Prune now empty partial
						scan list */
						dhd_iscan_free_buf(dhdp,
								   iscan_cur);
						goto done;
					}
					break;
				}
				bi = (wl_bss_info_t *)((unsigned long)bi +
							bi->length);
			}
		}
		iscan_cur = iscan_cur->next;
		l++;
	}

done:
	dhd_iscan_unlock();
	return 0;
}