예제 #1
0
void
dhd_conf_set_bw(dhd_pub_t *dhd)
{
	int bcmerror = -1;
	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
	uint32 mimo_bw_cap = 1; /* Turn HT40 on in 2.4 GHz */

	if (dhd_bus_chip_id(dhd) == BCM43341_CHIP_ID ||
			dhd_bus_chip_id(dhd) == BCM4324_CHIP_ID ||
			dhd_bus_chip_id(dhd) == BCM4335_CHIP_ID) {
		/* Enable HT40 in 2.4 GHz */
		printf("%s: Enable HT40 in 2.4 GHz\n", __FUNCTION__);
		bcm_mkiovar("mimo_bw_cap", (char *)&mimo_bw_cap, 4, iovbuf, sizeof(iovbuf));
		if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
			CONFIG_ERROR(("%s: mimo_bw_cap set failed %d\n", __FUNCTION__, bcmerror));
	}
}
예제 #2
0
void
dhd_conf_force_wme(dhd_pub_t *dhd)
{
    int bcmerror = -1;
    char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */

    if (dhd_bus_chip_id(dhd) == BCM43362_CHIP_ID && dhd->conf->force_wme_ac) {
        bcm_mkiovar("force_wme_ac", (char *)&dhd->conf->force_wme_ac, 4, iovbuf, sizeof(iovbuf));
        if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
            CONFIG_ERROR(("%s: force_wme_ac setting failed %d\n", __FUNCTION__, bcmerror));
    }
}
예제 #3
0
void
dhd_conf_set_phyoclscdenable(dhd_pub_t *dhd)
{
    int bcmerror = -1;
    char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
    uint phy_oclscdenable = 0;

    if (dhd_bus_chip_id(dhd) == BCM4324_CHIP_ID) {
        if (dhd->conf->phy_oclscdenable >= 0) {
            phy_oclscdenable = (uint)dhd->conf->phy_oclscdenable;
            printf("%s: set stbc_tx %d\n", __FUNCTION__, phy_oclscdenable);
            bcm_mkiovar("phy_oclscdenable", (char *)&phy_oclscdenable, 4, iovbuf, sizeof(iovbuf));
            if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
                CONFIG_ERROR(("%s: stbc_tx setting failed %d\n", __FUNCTION__, bcmerror));
        }
    }
}
int
wl_update_rssi_offset(int rssi)
{
	uint chip, chiprev;

	chip = dhd_bus_chip_id(bcmsdh_get_drvdata());
	chiprev = dhd_bus_chiprev_id(bcmsdh_get_drvdata());
	if (chip == BCM4330_CHIP_ID && chiprev == BCM4330B2_CHIP_REV) {
#if defined(RSSIOFFSET_NEW)
		int j;
		for (j=0; j<RSSI_OFFSET; j++) {
			if (rssi - (RSSI_MIN+RSSI_INT*(j+1)) < 0)
				break;
		}
		rssi += j;
#else
		rssi += RSSI_OFFSET;
#endif
	}
	if (rssi >= -2)
		rssi = -2;
	return rssi;
}
void
dhd_force_disable_singlcore_scan(dhd_pub_t *dhd)
{
	int ret = 0;
	struct file *fp = NULL;
	char *filepath = "/data/.cid.info";
	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
	char vender[10] = {0, };
	uint32 pm_bcnrx = 0;
	uint32 scan_ps = 0;

	if (BCM4354_CHIP_ID != dhd_bus_chip_id(dhd))
		return;

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("/data/.cid.info file open error\n"));
	} else {
		ret = kernel_read(fp, 0, (char *)vender, 5);

		if (ret > 0 && NULL != strstr(vender, "wisol")) {
			DHD_ERROR(("wisol module : set pm_bcnrx=0, set scan_ps=0\n"));

			bcm_mkiovar("pm_bcnrx", (char *)&pm_bcnrx, 4, iovbuf, sizeof(iovbuf));
			ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
			if (ret < 0)
				DHD_ERROR(("Set pm_bcnrx error (%d)\n", ret));

			bcm_mkiovar("scan_ps", (char *)&scan_ps, 4, iovbuf, sizeof(iovbuf));
			ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
			if (ret < 0)
				DHD_ERROR(("Set scan_ps error (%d)\n", ret));
		}
		filp_close(fp, NULL);
	}
}
예제 #6
0
void
dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *dst, char *src)
{
	int fw_type, ag_type;
	static uint chip, chiprev, first=1;
	int i;

	if (first) {
		chip = dhd_bus_chip_id(dhd);
		chiprev = dhd_bus_chiprev_id(dhd);
		first = 0;
	}

	if (src[0] == '\0') {
#ifdef CONFIG_BCMDHD_FW_PATH
		bcm_strncpy_s(src, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
		if (src[0] == '\0')
#endif
		{
			printf("src firmware path is null\n");
			return;
		}
	}

	strcpy(dst, src);
#ifndef FW_PATH_AUTO_SELECT
	return;
#endif

	/* find out the last '/' */
	i = strlen(dst);
	while (i>0){
		if (dst[i] == '/') break;
		i--;
	}
#ifdef BAND_AG
	ag_type = FW_TYPE_AG;
#else
	ag_type = strstr(&dst[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;
#endif
	fw_type = (strstr(&dst[i], "_mfg") ?
		FW_TYPE_MFG : (strstr(&dst[i], "_apsta") ?
		FW_TYPE_APSTA : (strstr(&dst[i], "_p2p") ?
		FW_TYPE_P2P : FW_TYPE_STA)));

	switch (chip) {
		case BCM4330_CHIP_ID:
			if (ag_type == FW_TYPE_G) {
				if (chiprev == BCM4330B2_CHIP_REV)
					strcpy(&dst[i+1], bcm4330b2_fw_name[fw_type]);
				break;
			} else {
				if (chiprev == BCM4330B2_CHIP_REV)
					strcpy(&dst[i+1], bcm4330b2ag_fw_name[fw_type]);
				break;
			}
		case BCM43362_CHIP_ID:
			if (chiprev == BCM43362A0_CHIP_REV)
				strcpy(&dst[i+1], bcm43362a0_fw_name[fw_type]);
			else
				strcpy(&dst[i+1], bcm43362a2_fw_name[fw_type]);
			break;
		case BCM43341_CHIP_ID:
			if (chiprev == BCM43341B0_CHIP_REV)
				strcpy(&dst[i+1], bcm43341b0ag_fw_name[fw_type]);
			break;
		case BCM4324_CHIP_ID:
			if (chiprev == BCM43241B4_CHIP_REV)
				strcpy(&dst[i+1], bcm43241b4ag_fw_name[fw_type]);
			break;
		case BCM4335_CHIP_ID:
			if (chiprev == BCM4335A0_CHIP_REV)
				strcpy(&dst[i+1], bcm4339a0ag_fw_name[fw_type]);
			break;
		case BCM4339_CHIP_ID:
			if (chiprev == BCM4339A0_CHIP_REV)
				strcpy(&dst[i+1], bcm4339a0ag_fw_name[fw_type]);
			break;
	}

	printf("%s: firmware_path=%s\n", __FUNCTION__, dst);
}
int dhd_sel_ant_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 ant_val = 0;
	uint32 btc_mode = 0;
	char *filepath = ANTINFO;
	char iovbuf[WLC_IOCTL_SMLEN];
	uint chip_id = dhd_bus_chip_id(dhd);

	/* Check if this chip can support MIMO */
	if (chip_id != BCM4324_CHIP_ID &&
		chip_id != BCM4350_CHIP_ID &&
		chip_id != BCM4356_CHIP_ID &&
		chip_id != BCM4354_CHIP_ID) {
		DHD_ERROR(("[WIFI_SEC] %s: This chipset does not support MIMO\n",
			__FUNCTION__));
		return ret;
	}

	/* Read antenna settings from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] open error\n", __FUNCTION__, filepath));
		return ret;
	} else {
		ret = kernel_read(fp, 0, (char *)&ant_val, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			return ret;
		}

		ant_val = bcm_atoi((char *)&ant_val);

		DHD_ERROR(("[WIFI_SEC]%s: ANT val = %d\n", __FUNCTION__, ant_val));
		filp_close(fp, NULL);

		/* Check value from the file */
		if (ant_val < 1 || ant_val > 3) {
			DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
				__FUNCTION__, ant_val, filepath));
			return -1;
		}
	}

	/* bt coex mode off */
	if (dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) {
		bcm_mkiovar("btc_mode", (char *)&btc_mode, 4, iovbuf, sizeof(iovbuf));
		ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
		if (ret) {
			DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
				"btc_mode, ret=%d\n",
				__FUNCTION__, ret));
			return ret;
		}
	}

	/* Select Antenna */
	bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	return 0;
}
예제 #8
0
int dhd_write_otp(dhd_pub_t *dhd)
{
	int ret;
	char buf[CIS_BUF_SIZE] = {0};
	char *bufp;
	const char *otp_vars;
	int otp_header_size;
	int otp_vars_size;
	uint32 len = 0;
	uint chipid;
	cis_rw_t cish;
	char *cisp, *cisdata;
	int max = 0;
	bool sta_mode = FALSE;
	cis_rw_t *cish_r = (cis_rw_t *)&buf[8];
	struct file *fp;
	mm_segment_t old_fs;
	loff_t pos = 0;

	chipid = dhd_bus_chip_id(dhd);

	if (chipid == BCM43569_CHIP_ID) {
		otp_vars = BCM4358A3_otp_vars;
		otp_vars_size = sizeof(BCM4358A3_otp_vars);
		otp_header_size = BCM4358A3_OTP_HEADER_SIZE;
	} else {
		DHD_ERROR(("%s: can't find OTP header for chip\n", __FUNCTION__));
		return BCME_ERROR;
	}

	cish_r->source = 0;
	cish_r->byteoff = 0;
	cish_r->nbytes = sizeof(buf);

	strcpy(buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), 0, 0);
	if (ret < 0) {
		DHD_ERROR(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n",
			__FUNCTION__, ret));
		sta_mode = TRUE;
		goto exit;
	}

	max = otp_header_size;
	if (memcmp(&buf[12], otp_vars, otp_header_size) == 0) {
		DHD_ERROR(("%s:OTP already was written\n", __FUNCTION__));
	} else {
		DHD_ERROR(("%s: OTP length: %d bytes \n", __FUNCTION__, otp_vars_size));

		max = sizeof(buf);
		bufp = buf;
		memset(buf, 0, sizeof(buf));
		strcpy(bufp, "ciswrite");
		bufp += strlen("ciswrite") + 1;
		cisp = bufp;
		cisdata = cisp + sizeof(cish);

		cish.source = htod32(0);

		memcpy(cisdata, (char *)otp_vars, otp_vars_size);
		len = otp_vars_size;

		cish.byteoff = htod32(0);
		cish.nbytes = htod32(len);
		memcpy(cisp, (char*)&cish, sizeof(cish));

		ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf,
			(cisp - buf) + sizeof(cish) + len, TRUE, 0);
		if (ret) {
			DHD_ERROR(("%s: Fail to write otp, ret = %d \n", __FUNCTION__, ret));
		} else {
			DHD_ERROR(("Success to write otp \n"));
		}
	}
	/* check or create .otp.info */
	old_fs = get_fs();
	set_fs(KERNEL_DS);

	fp = filp_open("/data/.otp.info", O_RDONLY, 0);
	if (IS_ERR(fp)) {

		/* prepare .otp.info data through reading OTP from chip  */
		memset(buf, 0, sizeof(buf));
		strcpy(buf, "cisdump");
		ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), 0, 0);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: CIS reading failed After writing ret=%d\n",
				__FUNCTION__, ret));
			goto exit;
		}

		/* create .otp.info */
		fp = filp_open("/data/.otp.info", O_RDWR|O_CREAT, 0666);
		if (!fp) {
			DHD_ERROR(("%s:(MFG mode) file create error\n", __FUNCTION__));
			return BCME_ERROR;
		}

		/* Write buf to file */
		fp->f_op->write(fp, buf, CIS_BUF_SIZE, &pos);
	}

	if (fp) {
		filp_close(fp, current->files);
	}
	DHD_ERROR(("%s: .otp.info is created or existing already\n", __FUNCTION__));
	/* restore previous address limit */
	set_fs(old_fs);

exit:
	if (sta_mode == TRUE) {
		fp = filp_open("/data/.otp.info", O_RDONLY, 0);
		if (IS_ERR(fp)) {
			DHD_ERROR(("%s: file open error.\n", __FUNCTION__));
			return BCME_ERROR;
		}

		ret = kernel_read(fp, 0, buf, CIS_BUF_SIZE);

		if (memcmp(&buf[12], otp_vars, otp_header_size) == 0) {
			DHD_ERROR(("%s: OTP checking -> OK\n", __FUNCTION__));
		} else {
			DHD_ERROR(("%s: OTP checking -> OTP has ERROR.\n", __FUNCTION__));
		}
		filp_close(fp, current->files);
	}
	return ret;
}