Esempio n. 1
0
static int wl_android_get_country_rev(
	struct net_device *dev, char *command, int total_len)
{
	int error;
	int bytes_written;
	char smbuf[WLC_IOCTL_SMLEN];
	wl_country_t cspec;

	error = wldev_iovar_getbuf(dev, "country", NULL, 0, smbuf,
		sizeof(smbuf), NULL);

	if (error) {
		DHD_ERROR(("%s: get country failed code %d\n",
			__FUNCTION__, error));
		return -1;
	} else {
		memcpy(&cspec, smbuf, sizeof(cspec));
		DHD_INFO(("%s: get country '%c%c %d'\n",
			__FUNCTION__, cspec.ccode[0], cspec.ccode[1], cspec.rev));
	}

	bytes_written = snprintf(command, total_len, "%s %c%c %d",
		CMD_COUNTRYREV_GET, cspec.ccode[0], cspec.ccode[1], cspec.rev);

	return bytes_written;
}
int
wldev_get_ap_status(struct net_device *dev)
{
	int res = 0;
	int ap = 0;
	int apsta = 0;
       	char smbuf[WLC_IOCTL_SMLEN];

	printf("%s: enter\n", __FUNCTION__);

        if (!dev) {
                WLDEV_ERROR(("%s: dev is null\n", __FUNCTION__));
                return -1;
        }

        if ((res = wldev_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap), 0))) {
                WLDEV_ERROR(("%s fail to get ap\n", __FUNCTION__));
		ap = 0;
	}

        if ((res = wldev_iovar_getbuf(dev, "apsta", &apsta, sizeof(apsta), smbuf, sizeof(smbuf), NULL)) < 0 ){
                WLDEV_ERROR(("%s fail to get apsta \n", __FUNCTION__));
        } else {
		memcpy(&apsta, smbuf, sizeof(apsta));
		apsta = dtoh32(apsta);
	}

	return (ap||apsta);
}
int wldev_set_country(
	struct net_device *dev, char *country_code, bool notify, bool user_enforced)
{
#ifdef TEGRA_REGION_BASED_NVRAM
	if (nv_dhd_set_nvram_params(country_code, dev)) {
		WLDEV_ERROR(("nvram params changed for country code: %s: Reload f/w\n", country_code));
		return 0;
	} else
		return -1;
#else /* TEGRA_REGION_BASED_NVRAM */
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];

	if (!country_code)
		return error;



	bzero(&scbval, sizeof(scb_val_t));
	error = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
	if (error < 0) {
		WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
		return error;
	}

	if ((error < 0) ||
	    (strncmp(country_code, cspec.ccode, WLC_CNTRY_BUF_SZ) != 0)) {

		if (user_enforced) {
			bzero(&scbval, sizeof(scb_val_t));
			error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
			if (error < 0) {
				WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
					__FUNCTION__, error));
				return error;
			}
		}

		cspec.rev = -1;
		memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
		memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
		get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
		error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
			smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
				__FUNCTION__, country_code, cspec.ccode, cspec.rev));
			return error;
		}
		dhd_bus_country_set(dev, &cspec, notify);
		WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
			__FUNCTION__, country_code, cspec.ccode, cspec.rev));
	}
	return 0;
#endif
}
Esempio n. 4
0
static int wl_android_get_assoc_res_ies(struct net_device *dev, char *command)
{
	int error;
	u8 buf[WL_ASSOC_INFO_MAX];
	wl_assoc_info_t assoc_info;
	u32 resp_ies_len = 0;
	int bytes_written = 0;

	WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev->name));

	error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, buf, WL_ASSOC_INFO_MAX, NULL);
	if (unlikely(error)) {
		WL_ERR(("could not get assoc info (%d)\n", error));
		return -1;
	}

	memcpy(&assoc_info, buf, sizeof(wl_assoc_info_t));
	assoc_info.req_len = htod32(assoc_info.req_len);
	assoc_info.resp_len = htod32(assoc_info.resp_len);
	assoc_info.flags = htod32(assoc_info.flags);

	if (assoc_info.resp_len) {
		resp_ies_len = assoc_info.resp_len - sizeof(struct dot11_assoc_resp);
	}

	/* first 4 bytes are ie len */
	memcpy(command, &resp_ies_len, sizeof(u32));
	bytes_written = sizeof(u32);

	/* get the association resp IE's if there are any */
	if (resp_ies_len) {
		error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0,
			buf, WL_ASSOC_INFO_MAX, NULL);
		if (unlikely(error)) {
			WL_ERR(("could not get assoc resp_ies (%d)\n", error));
			return -1;
		}

		memcpy(command+sizeof(u32), buf, resp_ies_len);
		bytes_written += resp_ies_len;
	}
	return bytes_written;
}
int wldev_get_rx_rate_stats(
	struct net_device *dev, char *command, int total_len)
{
	wl_scb_rx_rate_stats_t *rstats;
	struct ether_addr ea;
	char smbuf[WLC_IOCTL_SMLEN];
	char eabuf[18] = {0, };
	int bytes_written = 0;
	int error;

	memcpy(eabuf, command+strlen("RXRATESTATS")+1, 17);

	if (!bcm_ether_atoe(eabuf, &ea)) {
		WLDEV_ERROR(("Invalid MAC Address\n"));
		return -1;
	}

	error = wldev_iovar_getbuf(dev, "rx_rate_stats",
		&ea, ETHER_ADDR_LEN, smbuf, sizeof(smbuf), NULL);
	if (error < 0) {
		WLDEV_ERROR(("get rx_rate_stats failed = %d\n", error));
		return -1;
	}

	rstats = (wl_scb_rx_rate_stats_t *)smbuf;
	bytes_written = sprintf(command, "1/%d/%d,",
		dtoh32(rstats->rx1mbps[0]), dtoh32(rstats->rx1mbps[1]));
	bytes_written += sprintf(command+bytes_written, "2/%d/%d,",
		dtoh32(rstats->rx2mbps[0]), dtoh32(rstats->rx2mbps[1]));
	bytes_written += sprintf(command+bytes_written, "5.5/%d/%d,",
		dtoh32(rstats->rx5mbps5[0]), dtoh32(rstats->rx5mbps5[1]));
	bytes_written += sprintf(command+bytes_written, "6/%d/%d,",
		dtoh32(rstats->rx6mbps[0]), dtoh32(rstats->rx6mbps[1]));
	bytes_written += sprintf(command+bytes_written, "9/%d/%d,",
		dtoh32(rstats->rx9mbps[0]), dtoh32(rstats->rx9mbps[1]));
	bytes_written += sprintf(command+bytes_written, "11/%d/%d,",
		dtoh32(rstats->rx11mbps[0]), dtoh32(rstats->rx11mbps[1]));
	bytes_written += sprintf(command+bytes_written, "12/%d/%d,",
		dtoh32(rstats->rx12mbps[0]), dtoh32(rstats->rx12mbps[1]));
	bytes_written += sprintf(command+bytes_written, "18/%d/%d,",
		dtoh32(rstats->rx18mbps[0]), dtoh32(rstats->rx18mbps[1]));
	bytes_written += sprintf(command+bytes_written, "24/%d/%d,",
		dtoh32(rstats->rx24mbps[0]), dtoh32(rstats->rx24mbps[1]));
	bytes_written += sprintf(command+bytes_written, "36/%d/%d,",
		dtoh32(rstats->rx36mbps[0]), dtoh32(rstats->rx36mbps[1]));
	bytes_written += sprintf(command+bytes_written, "48/%d/%d,",
		dtoh32(rstats->rx48mbps[0]), dtoh32(rstats->rx48mbps[1]));
	bytes_written += sprintf(command+bytes_written, "54/%d/%d",
		dtoh32(rstats->rx54mbps[0]), dtoh32(rstats->rx54mbps[1]));

	return bytes_written;
}
int wldev_set_country(
	struct net_device *dev, char *country_code, bool notify, bool user_enforced, int revinfo)
{
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];

	if (!country_code)
		return error;

	bzero(&scbval, sizeof(scb_val_t));
	error = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
	if (error < 0) {
		WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
		return error;
	}

	if ((error < 0) ||
			dhd_force_country_change(dev) ||
	    (strncmp(country_code, cspec.ccode, WLC_CNTRY_BUF_SZ) != 0)) {

		if (user_enforced) {
			bzero(&scbval, sizeof(scb_val_t));
			error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
			if (error < 0) {
				WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
					__FUNCTION__, error));
				return error;
			}
		}

		cspec.rev = revinfo;
		memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
		memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
		dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
		error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
			smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
				__FUNCTION__, country_code, cspec.ccode, cspec.rev));
			return error;
		}
		dhd_bus_country_set(dev, &cspec, notify);
		WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
			__FUNCTION__, country_code, cspec.ccode, cspec.rev));
	}
	return 0;
}
s32 wldev_iovar_getint(
	struct net_device *dev, s8 *iovar, s32 *pval)
{
	s8 iovar_buf[WLC_IOCTL_SMLEN];
	s32 err;

	memset(iovar_buf, 0, sizeof(iovar_buf));
	err = wldev_iovar_getbuf(dev, iovar, pval, sizeof(*pval), iovar_buf,
		sizeof(iovar_buf), NULL);
	if (err == 0)
	{
		memcpy(pval, iovar_buf, sizeof(*pval));
		*pval = dtoh32(*pval);
	}
	return err;
}
Esempio n. 8
0
int
wl_cfgnan_support_handler(struct net_device *ndev,
	struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data)
{
	wl_nan_ioc_t *nanioc = NULL;
	void *pxtlv;
	s32 ret = BCME_OK;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE;

	nanioc = kzalloc(nanioc_size, kflags);
	if (!nanioc) {
		WL_ERR((" memory allocation failed \n"));
		return -ENOMEM;
	}

	/*
	 * command to test
	 *
	 * wl: wl nan
	 *
	 * wpa_cli: DRIVER NAN_SUPPORT
	 */

	/* nan support */
	nanioc->version = htod16(WL_NAN_IOCTL_VERSION);
	nanioc->id = htod16(WL_NAN_CMD_ENABLE);
	pxtlv = nanioc->data;
	nanioc->len = htod16(BCM_XTLV_HDR_SIZE + 1);
	nanioc_size = sizeof(wl_nan_ioc_t) + sizeof(bcm_xtlv_t);
	ret = wldev_iovar_getbuf(ndev, "nan", nanioc, nanioc_size,
		cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
	if (unlikely(ret)) {
		WL_ERR((" nan is not supported, error = %d \n", ret));
		goto fail;
	} else {
		WL_DBG((" nan is supported \n"));
	}

fail:
	if (nanioc) {
		kfree(nanioc);
	}

	return ret;
}
Esempio n. 9
0
int wldev_set_country(
	struct net_device *dev, char *country_code)
{
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];

	if (!country_code)
		return error;

	error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
		smbuf, sizeof(smbuf), NULL);
	if (error < 0)
		AP6210_ERR("%s: get country failed = %d\n", __FUNCTION__, error);

	if ((error < 0) ||
	    (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) {
		bzero(&scbval, sizeof(scb_val_t));
		error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
		if (error < 0) {
			AP6210_ERR("%s: set country failed due to Disassoc error %d\n",
				__FUNCTION__, error);
			return error;
		}
		cspec.rev = -1;
		memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
		memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
		get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
		error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
			smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
			AP6210_ERR("%s: set country for %s as %s rev %d failed\n",
				__FUNCTION__, country_code, cspec.ccode, cspec.rev);
			return error;
		}
		dhd_bus_country_set(dev, &cspec);
		AP6210_ERR("%s: set country for %s as %s rev %d\n",
			__FUNCTION__, country_code, cspec.ccode, cspec.rev);
	}
	return 0;
}
static int wl_android_get_country_rev(
		struct net_device *dev, char *command, int total_len)
{
	int error;
	int bytes_written;
	char smbuf[WLC_IOCTL_SMLEN];
	wl_country_t cspec;

	error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec), smbuf,
		sizeof(smbuf), NULL);

	if (error) {
		DHD_ERROR(("%s: get country failed code %d\n",
			__func__, error));
		return -1;
	} else {
		DHD_INFO(("%s: get country '%s %d'\n", __func__, smbuf, smbuf[WLC_CNTRY_BUF_SZ]));
	}
	bytes_written = snprintf(command, total_len, "%s %s %d", CMD_COUNTRYREV_GET, smbuf, smbuf[WLC_CNTRY_BUF_SZ]);
	return bytes_written;
}
Esempio n. 11
0
int
wl_cfgnan_status_handler(struct net_device *ndev,
	struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data)
{
	wl_nan_ioc_t *nanioc = NULL;
	void *pxtlv;
	char *ptr = cmd;
	wl_nan_tlv_data_t tlv_data;
	s32 ret = BCME_OK;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE;

	nanioc = kzalloc(nanioc_size, kflags);
	if (!nanioc) {
		WL_ERR((" memory allocation failed \n"));
		return -ENOMEM;
	}

	/*
	 * command to test
	 *
	 * wl: wl nan status
	 *
	 * wpa_cli: DRIVER NAN_STATUS
	 */

	/* nan status */
	nanioc->version = htod16(WL_NAN_IOCTL_VERSION);
	nanioc->id = htod16(WL_NAN_CMD_STATUS);
	pxtlv = nanioc->data;
	nanioc->len = NAN_IOCTL_BUF_SIZE;
	nanioc_size = sizeof(wl_nan_ioc_t) + sizeof(bcm_xtlv_t);
	ret = wldev_iovar_getbuf(ndev, "nan", nanioc, nanioc_size,
		cfg->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
	if (unlikely(ret)) {
		WL_ERR((" nan status failed, error = %d \n", ret));
		goto fail;
	} else {
		WL_DBG((" nan status successful \n"));
	}

	/* unpack the tlvs */
	memset(&tlv_data, 0, sizeof(tlv_data));
	nanioc = (wl_nan_ioc_t *)cfg->ioctl_buf;
	if (g_nan_debug) {
		prhex(" nanioc->data: ", (uint8 *)nanioc->data, nanioc->len);
	}
	bcm_unpack_xtlv_buf(&tlv_data, nanioc->data, nanioc->len,
		wl_cfgnan_set_vars_cbfn);

	ptr += sprintf(ptr, CLUS_ID_PREFIX MACF, ETHER_TO_MACF(tlv_data.clus_id));
	ptr += sprintf(ptr, " " ROLE_PREFIX"%d", tlv_data.dev_role);
	ptr += sprintf(ptr, " " AMR_PREFIX);
	ptr += bcm_format_hex(ptr, tlv_data.amr, NAN_MASTER_RANK_LEN);
	ptr += sprintf(ptr, " " AMBTT_PREFIX"0x%x", tlv_data.ambtt);
	ptr += sprintf(ptr, " " HOP_COUNT_PREFIX"%d", tlv_data.hop_count);

	WL_DBG((" formatted string for userspace: %s, len: %zu \n",
		cmd, strlen(cmd)));

fail:
	if (nanioc) {
		kfree(nanioc);
	}
	if (tlv_data.svc_info.data) {
		kfree(tlv_data.svc_info.data);
		tlv_data.svc_info.data = NULL;
		tlv_data.svc_info.dlen = 0;
	}
	if (tlv_data.vend_info.data) {
		kfree(tlv_data.vend_info.data);
		tlv_data.vend_info.data = NULL;
		tlv_data.vend_info.dlen = 0;
	}

	return ret;
}
int wldev_get_assoc_resp_ie(
	struct net_device *dev, char *command, int total_len)
{
	wl_assoc_info_t *assoc_info;
	char smbuf[WLC_IOCTL_SMLEN];
	char bssid[6], null_bssid[6];
	int resp_ies_len = 0;
	int bytes_written = 0;
	int error, i;

	bzero(bssid, 6);
	bzero(null_bssid, 6);

	/* Check Association */
	error = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0);
	if (error == BCME_NOTASSOCIATED) {
		/* Not associated */
		bytes_written += snprintf(&command[bytes_written], total_len, "NA");
		goto done;
	}
	else if (error < 0) {
		WLDEV_ERROR(("WLC_GET_BSSID failed = %d\n", error));
		return -1;
	}
	else if (memcmp(bssid, null_bssid, ETHER_ADDR_LEN) == 0) {
		/*  Zero BSSID: Not associated */
		bytes_written += snprintf(&command[bytes_written], total_len, "NA");
		goto done;
	}

	/* Get assoc_info */
	bzero(smbuf, sizeof(smbuf));
	error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, smbuf, sizeof(smbuf), NULL);
	if (error < 0) {
		WLDEV_ERROR(("get assoc_info failed = %d\n", error));
		return -1;
	}

	assoc_info = (wl_assoc_info_t *)smbuf;
	resp_ies_len = dtoh32(assoc_info->resp_len) - sizeof(struct dot11_assoc_resp);

	/* Retrieve assoc resp IEs */
	if (resp_ies_len) {
		error = wldev_iovar_getbuf(dev, "assoc_resp_ies",
			NULL, 0, smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
			WLDEV_ERROR(("get assoc_resp_ies failed = %d\n", error));
			return -1;
		}

		/* Length */
		bytes_written += snprintf(&command[bytes_written], total_len, "%d,", resp_ies_len);

		/* IEs */
		if ((total_len - bytes_written) > resp_ies_len) {
			for (i = 0; i < resp_ies_len; i++) {
				bytes_written += sprintf(&command[bytes_written], "%02x", smbuf[i]);
			}
		} else {
			WLDEV_ERROR(("Not enough buffer\n"));
			return -1;
		}
	} else {
		WLDEV_ERROR(("Zero Length assoc resp ies = %d\n", resp_ies_len));
		return -1;
	}

done:

	return bytes_written;
}
Esempio n. 13
0
int wldev_set_country(
	struct net_device *dev, char *country_code)
{
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];
	
	uint32 chan_buf[WL_NUMCHANNELS];
	wl_uint32_list_t *list;
	channel_info_t ci;
	int retry = 0;
	int chan = 1;
	

	if (!country_code)
		return error;

	error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
		smbuf, sizeof(smbuf), NULL);
	if (error < 0)
		WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));

	if ((error < 0) ||
	    (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) {
		bzero(&scbval, sizeof(scb_val_t));
		error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), 1);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
				__FUNCTION__, error));
			return error;
		}
		error = wldev_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan), 1);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country failed due to channel 1 error %d\n",
				__FUNCTION__, error));
			return error;
		}
	}

get_channel_retry:
	if ((error = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci), 0))) {
		WLDEV_ERROR(("%s: get channel fail!\n", __FUNCTION__));
		return error;
	}
	ci.scan_channel = dtoh32(ci.scan_channel);
	if (ci.scan_channel) {
		retry++;
		printf("%s: scan in progress, retry %d!\n", __FUNCTION__, retry);
		if (retry > 3)
			return -EBUSY;
		bcm_mdelay(1000);
		goto get_channel_retry;
	}

	cspec.rev = -1;
	memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
	memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
	get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
	error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
		smbuf, sizeof(smbuf), NULL);
	if (error < 0) {
	
		if (strcmp(cspec.country_abbrev, DEF_COUNTRY_CODE) != 0) {
			strcpy(country_code, DEF_COUNTRY_CODE);
			retry = 0;
			goto get_channel_retry;
		}
		else {
			WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
				__FUNCTION__, country_code, cspec.ccode, cspec.rev));
			return error;
		}
	}
	
	else {
		if (strcmp(country_code, DEF_COUNTRY_CODE) != 0) {
			list = (wl_uint32_list_t *)(void *)chan_buf;
			list->count = htod32(WL_NUMCHANNELS);
			if ((error = wldev_ioctl_no_memset(dev, WLC_GET_VALID_CHANNELS, &chan_buf, sizeof(chan_buf), 0))) {
				WLDEV_ERROR(("%s: get channel list fail! %d\n", __FUNCTION__, error));
				return error;
			}
			
			printf("%s: channel_count = %d\n", __FUNCTION__, list->count);
			if (list->count == 0) {
				strcpy(country_code, DEF_COUNTRY_CODE);
				retry = 0;
				goto get_channel_retry;
			}
		}	
	}
	
	dhd_bus_country_set(dev, &cspec);
	printk(KERN_INFO "[WLAN] %s: set country for %s as %s rev %d\n",
		__func__, country_code, cspec.ccode, cspec.rev);
	
	wl_cfg80211_abort_connecting();
	
	return 0;
}
Esempio n. 14
0
int wldev_set_country(
	struct net_device *dev, char *country_code, bool notify, bool user_enforced)
{
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];

//CY+ default country when set country fail
	char default_country[10] = "XY";
//CY-
#ifdef CHIPNUM
	uint chipnum = 0;
#endif

	if (!country_code)
		return error;

	bzero(&scbval, sizeof(scb_val_t));
	error = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
	if (error < 0) {
		WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
		return error;
	}

//CY+ always set country
#if 0
	if ((error < 0) ||
	    (strncmp(country_code, cspec.country_abbrev, WLC_CNTRY_BUF_SZ) != 0)) {
#else
	if(true){
#endif
//CY- always set country

		if (user_enforced) {
			bzero(&scbval, sizeof(scb_val_t));
			error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
			if (error < 0) {
				WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
					__FUNCTION__, error));
				return error;
			}
		}

		cspec.rev = -1;
		memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
		memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
#ifdef CHIPNUM
		chipnum = dhd_get_chipnum(dev);
		printk("%s: chipnum:%d\n", __FUNCTION__, chipnum);
		dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec, chipnum);

//CY+ set default country
//BCM43340: XY
//BCM43362: XV
//BCM4343s: XV
		if (chipnum == 43430){
			sprintf(default_country, "XV");
		}else if (chipnum == 43362){
			sprintf(default_country, "XV");
		}else {
			sprintf(default_country, "XY");
		}
		WLDEV_ERROR(("%s: set default country to %s for CHIP %d\n", __FUNCTION__, default_country, chipnum));
//CY-

#else
		dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
#endif

		error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
			smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country for %s as %s rev %d failed, try to use %s\n",
				__FUNCTION__, country_code, cspec.ccode, cspec.rev, default_country));
			//return error;

			//if set country error, use default_country
			cspec.rev = -1;
			memcpy(cspec.country_abbrev, default_country, WLC_CNTRY_BUF_SZ);
			memcpy(cspec.ccode, default_country, WLC_CNTRY_BUF_SZ);

#ifdef CHIPNUM
			dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec, chipnum);
#else
			dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
#endif

			error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
				smbuf, sizeof(smbuf), NULL);
			if (error < 0) {
				WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
					__FUNCTION__, country_code, cspec.ccode, cspec.rev));
				return error;
			}
		}
		dhd_bus_country_set(dev, &cspec, notify);
		WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
			__FUNCTION__, country_code, cspec.ccode, cspec.rev));
	}
	return 0;
}

#if defined(CUSTOM_PLATFORM_NV_TEGRA)
/* tuning performance for miracast */
int wldev_miracast_tuning(
	struct net_device *dev, char *command, int total_len)
{
	int error = 0;
	int mode = 0;
	int ampdu_mpdu;
	int roam_off;
#ifdef VSDB_BW_ALLOCATE_ENABLE
	int mchan_algo;
	int mchan_bw;
#endif /* VSDB_BW_ALLOCATE_ENABLE */

	if (sscanf(command, "%*s %d", &mode) != 1) {
		WLDEV_ERROR(("Failed to get mode\n"));
		return -1;
	}

	WLDEV_ERROR(("mode: %d\n", mode));

	if (mode == 0) {
		/* Normal mode: restore everything to default */
		ampdu_mpdu = -1;	/* FW default */
#if defined(ROAM_ENABLE)
		roam_off = 0;	/* roam enable */
#elif defined(DISABLE_BUILTIN_ROAM)
		roam_off = 1;	/* roam disable */
#endif
#ifdef VSDB_BW_ALLOCATE_ENABLE
		mchan_algo = 0;	/* Default */
		mchan_bw = 50;	/* 50:50 */
#endif /* VSDB_BW_ALLOCATE_ENABLE */
	}
	else if (mode == 1) {
		/* Miracast source mode */
		ampdu_mpdu = 8;	/* for tx latency */
#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
		roam_off = 1; /* roam disable */
#endif
#ifdef VSDB_BW_ALLOCATE_ENABLE
		mchan_algo = 1;	/* BW based */
		mchan_bw = 25;	/* 25:75 */
#endif /* VSDB_BW_ALLOCATE_ENABLE */
	}
	else if (mode == 2) {
		/* Miracast sink/PC Gaming mode */
		ampdu_mpdu = -1;	/* FW default */
#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
		roam_off = 1; /* roam disable */
#endif
#ifdef VSDB_BW_ALLOCATE_ENABLE
		mchan_algo = 0;	/* Default */
		mchan_bw = 50;	/* 50:50 */
#endif /* VSDB_BW_ALLOCATE_ENABLE */
	}
	else {
		WLDEV_ERROR(("Unknown mode: %d\n", mode));
		return -1;
	}

	/* Update ampdu_mpdu */
	error = wldev_iovar_setint(dev, "ampdu_mpdu", ampdu_mpdu);
	if (error) {
		WLDEV_ERROR(("Failed to set ampdu_mpdu: mode:%d, error:%d\n",
			mode, error));
		return -1;
	}

#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
	error = wldev_iovar_setint(dev, "roam_off", roam_off);
	if (error) {
		WLDEV_ERROR(("Failed to set roam_off: mode:%d, error:%d\n",
			mode, error));
		return -1;
	}
#endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */

#ifdef VSDB_BW_ALLOCATE_ENABLE
	error = wldev_iovar_setint(dev, "mchan_algo", mchan_algo);
	if (error) {
		WLDEV_ERROR(("Failed to set mchan_algo: mode:%d, error:%d\n",
			mode, error));
		return -1;
	}

	error = wldev_iovar_setint(dev, "mchan_bw", mchan_bw);
	if (error) {
		WLDEV_ERROR(("Failed to set mchan_bw: mode:%d, error:%d\n",
			mode, error));
		return -1;
	}
#endif /* VSDB_BW_ALLOCATE_ENABLE */

	return error;
}
int wldev_set_country(
	struct net_device *dev, char *country_code, bool notify, bool user_enforced)
{
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];
#ifdef CUSTOMER_HW_ONE
	uint32 chan_buf[WL_NUMCHANNELS];
	wl_uint32_list_t *list;
	channel_info_t ci;
	int retry = 0;
	int chan = 1;
#endif
	if (!country_code)
		return error;

	bzero(&scbval, sizeof(scb_val_t));
	error = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
	if (error < 0) {
		WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
		return error;
	}

	if ((error < 0) ||
	    (strncmp(country_code, cspec.country_abbrev, WLC_CNTRY_BUF_SZ) != 0)) {

		if (user_enforced) {
			bzero(&scbval, sizeof(scb_val_t));
			error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
			if (error < 0) {
				WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
					__FUNCTION__, error));
				return error;
			}
		}

#ifdef CUSTOMER_HW_ONE
		error = wldev_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan), 1);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country failed due to channel 1 error %d\n",
				__FUNCTION__, error));
			return error;
		}
	}

get_channel_retry:
	if ((error = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci), 0))) {
		WLDEV_ERROR(("%s: get channel fail!\n", __FUNCTION__));
		return error;
	}
	ci.scan_channel = dtoh32(ci.scan_channel);
	if (ci.scan_channel) {
		retry++;
		printf("%s: scan in progress, retry %d!\n", __FUNCTION__, retry);
		if (retry > 3)
			return -EBUSY;
		bcm_mdelay(1000);
		goto get_channel_retry;
	}
#endif
		cspec.rev = -1;
		memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
		memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
		get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
		error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
			smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
#ifdef CUSTOMER_HW_ONE
			if (strcmp(cspec.country_abbrev, DEF_COUNTRY_CODE) != 0) {
				strcpy(country_code, DEF_COUNTRY_CODE);
				retry = 0;
				goto get_channel_retry;
			}
			else {
#endif
				WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
					__FUNCTION__, country_code, cspec.ccode, cspec.rev));
				return error;
			}
#ifdef CUSTOMER_HW_ONE
		}
		/* check if there are available channels */
		else {
			if (strcmp(country_code, DEF_COUNTRY_CODE) != 0) {
				list = (wl_uint32_list_t *)(void *)chan_buf;
				list->count = htod32(WL_NUMCHANNELS);
				if ((error = wldev_ioctl_no_memset(dev, WLC_GET_VALID_CHANNELS, &chan_buf, sizeof(chan_buf), 0))) {
					WLDEV_ERROR(("%s: get channel list fail! %d\n", __FUNCTION__, error));
					return error;
				}
				/* if NULL, set default country code instead and set country code again */
				printf("%s: channel_count = %d\n", __FUNCTION__, list->count);
				if (list->count == 0) {
					strcpy(country_code, DEF_COUNTRY_CODE);
					retry = 0;
					goto get_channel_retry;
				}
		}	
#endif
		dhd_bus_country_set(dev, &cspec, notify);
		WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
			__FUNCTION__, country_code, cspec.ccode, cspec.rev));
	}
#ifdef CUSTOMER_HW_ONE
	wl_cfg80211_abort_connecting();
#endif
	return 0;
}
int wldev_get_max_linkspeed(
	struct net_device *dev, char *command, int total_len)
{
	wl_assoc_info_t *assoc_info;
	char smbuf[WLC_IOCTL_SMLEN];
	char bssid[6], null_bssid[6];
	int resp_ies_len = 0;
	int bytes_written = 0;
	int error, i;

	bzero(bssid, 6);
	bzero(null_bssid, 6);

	/* Check Association */
	error = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0);
	if (error == BCME_NOTASSOCIATED) {
		/* Not associated */
		bytes_written += snprintf(&command[bytes_written],
					total_len, "-1");
		goto done;
	} else if (error < 0) {
		WLDEV_ERROR(("WLC_GET_BSSID failed = %d\n", error));
		return -1;
	} else if (memcmp(bssid, null_bssid, ETHER_ADDR_LEN) == 0) {
		/*  Zero BSSID: Not associated */
		bytes_written += snprintf(&command[bytes_written],
					total_len, "-1");
		goto done;
	}
	/* Get assoc_info */
	bzero(smbuf, sizeof(smbuf));
	error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, smbuf,
				sizeof(smbuf), NULL);
	if (error < 0) {
		WLDEV_ERROR(("get assoc_info failed = %d\n", error));
		return -1;
	}

	assoc_info = (wl_assoc_info_t *)smbuf;
	resp_ies_len = dtoh32(assoc_info->resp_len) -
				sizeof(struct dot11_assoc_resp);

	/* Retrieve assoc resp IEs */
	if (resp_ies_len) {
		error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0,
					smbuf, sizeof(smbuf), NULL);
		if (error < 0) {
			WLDEV_ERROR(("get assoc_resp_ies failed = %d\n",
				error));
			return -1;
		}

		{
			int maxRate = 0;
			struct dot11IE {
				unsigned char ie;
				unsigned char len;
				unsigned char data[0];
			} *dot11IE = (struct dot11IE *)smbuf;
			int remaining = resp_ies_len;

			while (1) {
				if (remaining < 2)
					break;
				if (remaining < dot11IE->len + 2)
					break;
				switch (dot11IE->ie) {
				case 0x01: /* supported rates */
				case 0x32: /* extended supported rates */
					for (i = 0; i < dot11IE->len; i++) {
						int rate = ((dot11IE->data[i] &
								0x7f) / 2);
						if (rate > maxRate)
							maxRate = rate;
					}
					break;
				case 0x2d: /* HT capabilities */
				case 0x3d: /* HT operation */
					/* 11n supported */
					maxRate = 150; /* Just return an 11n
					rate for now. Could implement detailed
					parser later. */
					break;
				default:
					break;
				}

				/* next IE */
				dot11IE = (struct dot11IE *)
				((unsigned char *)dot11IE + dot11IE->len + 2);
				remaining -= (dot11IE->len + 2);
			}
			bytes_written += snprintf(&command[bytes_written],
						total_len, "MaxLinkSpeed %d",
						maxRate);
			goto done;
			}
	} else {
		WLDEV_ERROR(("Zero Length assoc resp ies = %d\n",
			resp_ies_len));
		return -1;
	}

done:

	return bytes_written;

}
Esempio n. 17
0
int wldev_set_country(
	struct net_device *dev, char *country_code)
{
	int error = -1;
	wl_country_t cspec = {{0}, 0, {0}};
	scb_val_t scbval;
	char smbuf[WLC_IOCTL_SMLEN];

	if (!country_code)
		return error;

	error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
		smbuf, sizeof(smbuf), NULL);
	if (error < 0)
		WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));

	if ((error < 0) ||
	    (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) {
		bzero(&scbval, sizeof(scb_val_t));
		error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), 1);
		if (error < 0) {
			WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
				__FUNCTION__, error));
			return error;
		}
	}
	cspec.rev = -1;
	//[email protected] - Country Code and rev from framework
	//memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
	//memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
	//get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
	{
		char *revstr;
		char *endptr = NULL;
	
		revstr = strchr(country_code, '/');
		if (revstr) 
		{
			cspec.rev = bcm_strtoul(revstr + 1, &endptr, 10);
			memcpy(cspec.country_abbrev,country_code,WLC_CNTRY_BUF_SZ);
			cspec.country_abbrev[2] = '\0';
			memcpy(cspec.ccode,cspec.country_abbrev,WLC_CNTRY_BUF_SZ);
		}
		else
		{
#if defined (CONFIG_PRODUCT_I_ATNT) || defined(CONFIG_PRODUCT_I_BELL) || defined(CONFIG_PRODUCT_J_TLS)
			memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
			memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
			get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
#else
			cspec.rev = 0;
			memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
			memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
#endif

		}
	}
	WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",	__FUNCTION__, country_code, cspec.ccode, cspec.rev));
	//[email protected] - Country Code and rev from framework	
	
	error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
		smbuf, sizeof(smbuf), NULL);
	if (error < 0) {
		WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
			__FUNCTION__, country_code, cspec.ccode, cspec.rev));
		return error;
	}
	dhd_bus_country_set(dev, &cspec);
	WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
		__FUNCTION__, country_code, cspec.ccode, cspec.rev));
	return 0;
}