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;
}
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;
}