int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	unsigned char mac_buf[20] = {0};
	unsigned char otp_mac_buf[20] = {0};
	const char *macfilepath = MACINFO_EFS;

	/* Try reading out from CIS */
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	struct file *fp_mac = NULL;

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_TRACE(("%s: CIS reading failed, err=%d\n", __func__,
			ret));
		sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			mac->octet[0], mac->octet[1], mac->octet[2],
			mac->octet[3], mac->octet[4], mac->octet[5]);
		DHD_ERROR(("%s: Check module mac by legacy FW : %02X:%02X:%02X\n",
			__func__, mac->octet[0], mac->octet[4], mac->octet[5]));
	} else {
		unsigned char mac_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#ifdef DUMP_CIS
		dhd_dump_cis(cis_buf, 48);
#endif
		mac_id[0] = cis_buf[CIS_MAC_OFFSET];
		mac_id[1] = cis_buf[CIS_MAC_OFFSET + 1];
		mac_id[2] = cis_buf[CIS_MAC_OFFSET + 2];
		mac_id[3] = cis_buf[CIS_MAC_OFFSET + 3];
		mac_id[4] = cis_buf[CIS_MAC_OFFSET + 4];
		mac_id[5] = cis_buf[CIS_MAC_OFFSET + 5];

		sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			mac_id[0], mac_id[1], mac_id[2], mac_id[3], mac_id[4],
			mac_id[5]);
		DHD_ERROR(("[WIFI]mac_id is setted from OTP \n"));
	}

	fp_mac = filp_open(macfilepath, O_RDONLY, 0);
	if (!IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI]Check Mac address in .mac.info \n"));
		kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
		filp_close(fp_mac, NULL);

		if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
			DHD_ERROR(("[WIFI]file MAC is wrong. Write OTP MAC in .mac.info \n"));
			dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
		}
	}

	return ret;
}
int dhd_check_module_cid(dhd_pub_t *dhd)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	const char *cidfilepath = CIDINFO;
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	int idx, max;
	vid_info_t *cur_info;
	unsigned char *vid_start;
	unsigned char vid_length;
#if defined(BCM4334_CHIP) || defined(BCM4335_CHIP)
	const char *revfilepath = REVINFO;
#ifdef BCM4334_CHIP
	int flag_b3;
#else
	char rev_str[10] = {0};
#endif /* BCM4334_CHIP */
#endif /* BCM4334_CHIP || BCM4335_CHIP */

	/* Try reading out from CIS */
	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_ERROR(("%s: CIS reading failed, err=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	DHD_ERROR(("%s: CIS reading success, ret=%d\n",
		__FUNCTION__, ret));
#ifdef DUMP_CIS
	dhd_dump_cis(cis_buf, 48);
#endif

	max = sizeof(cis_buf) - 4;
	for (idx = 0; idx < max; idx++) {
		if (cis_buf[idx] == CIS_TUPLE_START) {
			if (cis_buf[idx + 2] == CIS_TUPLE_VENDOR) {
				vid_length = cis_buf[idx + 1];
				vid_start = &cis_buf[idx + 3];
				/* found CIS tuple */
				break;
			} else {
				/* Go to next tuple if tuple value is not vendor type */
				idx += (cis_buf[idx + 1] + 1);
			}
		}
	}

	if (idx < max) {
		max = sizeof(vid_info) / sizeof(vid_info_t);
		for (idx = 0; idx < max; idx++) {
			cur_info = &vid_info[idx];
			if ((cur_info->vid_length == vid_length) &&
				(cur_info->vid_length != 0) &&
				(memcmp(cur_info->vid, vid_start, cur_info->vid_length - 1) == 0))
				goto write_cid;
		}
	}

	/* find default nvram, if exist */
	DHD_ERROR(("%s: cannot find CIS TUPLE set as default\n", __FUNCTION__));
	max = sizeof(vid_info) / sizeof(vid_info_t);
	for (idx = 0; idx < max; idx++) {
		cur_info = &vid_info[idx];
		if (cur_info->vid_length == 0)
			goto write_cid;
	}
	DHD_ERROR(("%s: cannot find default CID\n", __FUNCTION__));
	return -1;

write_cid:
	DHD_ERROR(("CIS MATCH FOUND : %s\n", cur_info->vname));
	dhd_write_cid_file(cidfilepath, cur_info->vname, strlen(cur_info->vname)+1);
#if defined(BCM4334_CHIP)
	/* Try reading out from OTP to distinguish B2 or B3 */
	memset(cis_buf, 0, sizeof(cis_buf));
	cish = (cis_rw_t *)&cis_buf[8];

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "otpdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_ERROR(("%s: OTP reading failed, err=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	/* otp 33th character is identifier for 4334B3 */
	cis_buf[34] = '\0';
	flag_b3 = bcm_atoi(&cis_buf[33]);
	if (flag_b3 & 0x1) {
		DHD_ERROR(("REV MATCH FOUND : 4334B3, %c\n", cis_buf[33]));
		dhd_write_cid_file(revfilepath, "4334B3", 6);
	}
#endif /* BCM4334_CHIP */
#if defined(BCM4335_CHIP)
	DHD_TRACE(("%s: BCM4335 Multiple Revision Check\n", __FUNCTION__));
	if (concate_revision(dhd->bus, rev_str, sizeof(rev_str),
		rev_str, sizeof(rev_str)) < 0) {
		DHD_ERROR(("%s: fail to concate revision\n", __FUNCTION__));
		ret = -1;
	} else {
		if (strstr(rev_str, "_a0")) {
			DHD_ERROR(("REV MATCH FOUND : 4335A0\n"));
			dhd_write_cid_file(revfilepath, "BCM4335A0", 9);
		} else {
			DHD_ERROR(("REV MATCH FOUND : 4335B0\n"));
			dhd_write_cid_file(revfilepath, "BCM4335B0", 9);
		}
	}
#endif /* BCM4335_CHIP */

	return ret;
}
int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	unsigned char mac_buf[20] = {0};
	unsigned char otp_mac_buf[20] = {0};
	const char *macfilepath = MACINFO_EFS;

	/* Try reading out from CIS */
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	struct file *fp_mac = NULL;

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_TRACE(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n", __func__,
			ret));
		sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			mac->octet[0], mac->octet[1], mac->octet[2],
			mac->octet[3], mac->octet[4], mac->octet[5]);
		DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n",
			__FUNCTION__, MAC2STRDBG(mac->octet)));
	} else {
		bcm_tlv_t *elt = NULL;
		int remained_len = sizeof(cis_buf);
		int index = 0;
		uint8 *mac_addr = NULL;
#ifdef DUMP_CIS
		dhd_dump_cis(cis_buf, 48);
#endif

		/* Find a new tuple tag */
		while (index < remained_len) {
			if (cis_buf[index] == CIS_TUPLE_TAG_START) {
				remained_len -= index;
				if (remained_len >= sizeof(bcm_tlv_t)) {
					elt = (bcm_tlv_t *)&cis_buf[index];
				}
				break;
			} else {
				index++;
			}

		}

		/* Find a MAC address tuple */
		while (elt && remained_len >= TLV_HDR_LEN) {
			int body_len = (int)elt->len;

			if ((elt->id == CIS_TUPLE_TAG_START) &&
				(remained_len >= (body_len + TLV_HDR_LEN)) &&
				(*elt->data == CIS_TUPLE_TAG_MACADDR)) {
				/* found MAC Address tuple and
				 * get the MAC Address data
				 */
				mac_addr = (uint8 *)elt + CIS_TUPLE_TAG_MACADDR_OFF;
				break;
			}

			/* Go to next tuple if tuple value
			 * is not MAC address type
			 */
			elt = (bcm_tlv_t *)((uint8 *)elt + (body_len + TLV_HDR_LEN));
			remained_len -= (body_len + TLV_HDR_LEN);
		}

		if (mac_addr) {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				mac_addr[0], mac_addr[1], mac_addr[2],
				mac_addr[3], mac_addr[4], mac_addr[5]);
			DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n"));
		} else {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				mac->octet[0], mac->octet[1], mac->octet[2],
				mac->octet[3], mac->octet[4], mac->octet[5]);
			DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP,"
				" Check module mac by initial value: " MACDBG "\n",
				__FUNCTION__, MAC2STRDBG(mac->octet)));
		}
	}

	fp_mac = filp_open(macfilepath, O_RDONLY, 0);
	if (!IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n"));
		kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
		filp_close(fp_mac, NULL);

		if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
			DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n"));
			dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
		}
	}

	return ret;
}
int dhd_check_module_cid(dhd_pub_t *dhd)
{
	int ret = -1;
#ifdef BCM4334_CHIP
	unsigned char cis_buf[250] = {0};
	const char *revfilepath = REVINFO;
	int flag_b3 = 0;
#else
	unsigned char cis_buf[128] = {0};
#endif
	const char *cidfilepath = CIDINFO;

	/* Try reading out from CIS */
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_TRACE(("%s: CIS reading failed, err=%d\n",
			__FUNCTION__, ret));
		return ret;
	} else {
#ifdef BCM4334_CHIP
		unsigned char semco_id[4] = {0x00, 0x00, 0x33, 0x33};

		/* for SHARP FEM(new) */
		unsigned char semco_id_sh[4] = {0x00, 0x00, 0xFB, 0x50};
		DHD_ERROR(("%s: CIS reading success, ret=%d\n",
			__FUNCTION__, ret));
#ifdef DUMP_CIS
		dump_cis(cis_buf, 48);
#endif
		if (memcmp(&cis_buf[CIS_CID_OFFSET], semco_id, 4) == 0) {
			DHD_ERROR(("CID MATCH FOUND : Semco, "
				"0x%02X 0x%02X 0x%02X 0x%02X\n",
				cis_buf[CIS_CID_OFFSET],
				cis_buf[CIS_CID_OFFSET+1], cis_buf[CIS_CID_OFFSET+2],
				cis_buf[CIS_CID_OFFSET+3]));
			dhd_write_cid_file(cidfilepath, "semco", 5);
		} else if (memcmp(&cis_buf[CIS_CID_OFFSET], semco_id_sh, 4) == 0) {
			DHD_ERROR(("CIS MATCH FOUND : Semco_sh, "
				"0x%02X 0x%02X 0x%02X 0x%02X\n",
				cis_buf[CIS_CID_OFFSET],
				cis_buf[CIS_CID_OFFSET+1], cis_buf[CIS_CID_OFFSET+2],
				cis_buf[CIS_CID_OFFSET+3]));
			dhd_write_cid_file(cidfilepath, "semcosh", 7);
		} else {
			DHD_ERROR(("CID MATCH FOUND : Murata, "
				"0x%02X 0x%02X 0x%02X 0x%02X\n", cis_buf[CIS_CID_OFFSET],
				cis_buf[CIS_CID_OFFSET+1], cis_buf[CIS_CID_OFFSET+2],
				cis_buf[CIS_CID_OFFSET+3]));
			dhd_write_cid_file(cidfilepath, "murata", 6);
		}

		/* Try reading out from OTP to distinguish B2 or B3 */
		memset(cis_buf, 0, sizeof(cis_buf));
		cish = (cis_rw_t *)&cis_buf[8];

		cish->source = 0;
		cish->byteoff = 0;
		cish->nbytes = sizeof(cis_buf);

		strcpy(cis_buf, "otpdump");
		ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
			sizeof(cis_buf), 0, 0);
		if (ret < 0) {
			DHD_ERROR(("%s: OTP reading failed, err=%d\n",
				__FUNCTION__, ret));
			return ret;
		}

		/* otp 33th character is identifier for 4334B3 */
		cis_buf[34] = '\0';
		flag_b3 = bcm_atoi(&cis_buf[33]);
		if (flag_b3 & 0x1) {
			DHD_ERROR(("REV MATCH FOUND : 4334B3, %c\n", cis_buf[33]));
			dhd_write_cid_file(revfilepath, "4334B3", 6);
		}

#else /* BCM4330_CHIP */
		unsigned char murata_id[4] = {0x80, 0x06, 0x81, 0x00};
		unsigned char semco_ve[4] = {0x80, 0x02, 0x81, 0x99};
#ifdef DUMP_CIS
		dhd_dump_cis(cis_buf, 48);
#endif
		if (memcmp(&cis_buf[CIS_CID_OFFSET], murata_id, 4) == 0) {
			DHD_ERROR(("CID MATCH FOUND : Murata\n"));
			dhd_write_cid_file(cidfilepath, "murata", 6);
		} else if (memcmp(&cis_buf[CIS_CID_OFFSET], semco_ve, 4)
			== 0) {
			DHD_ERROR(("CID MATCH FOUND : Semco VE\n"));
			dhd_write_cid_file(cidfilepath, "semcove", 7);
		} else {
			DHD_ERROR(("CID MISMATCH"
				" 0x%02X 0x%02X 0x%02X 0x%02X\n",
				cis_buf[CIS_CID_OFFSET],
				cis_buf[CIS_CID_OFFSET + 1],
				cis_buf[CIS_CID_OFFSET + 2],
				cis_buf[CIS_CID_OFFSET + 3]));
			dhd_write_cid_file(cidfilepath, "samsung", 7);
		}
#endif /* BCM4334_CHIP */
		DHD_ERROR(("%s: CIS write success, err=%d\n",
			__FUNCTION__, ret));
	}

	return ret;
}
int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	unsigned char mac_buf[20] = {0};
	unsigned char otp_mac_buf[20] = {0};
	const char *macfilepath = MACINFO_EFS;

	/* Try reading out from CIS */
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	struct file *fp_mac = NULL;

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_INFO(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n",
			__FUNCTION__, ret));

		sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			mac->octet[0], mac->octet[1], mac->octet[2],
			mac->octet[3], mac->octet[4], mac->octet[5]);
		DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n",
			__FUNCTION__, MAC2STRDBG(mac->octet)));
	} else {
		int max, idx, macaddr_idx;
#ifdef DUMP_CIS
		dhd_dump_cis(cis_buf, 48);
#endif

		/* Find a new tuple tag */
		max = sizeof(cis_buf) - 8;
		for (idx = 0; idx < max; idx++) {
			if (cis_buf[idx] == CIS_TUPLE_TAG_START) {
				if (cis_buf[idx + 2] == CIS_TUPLE_TAG_MACADDR &&
					cis_buf[idx + 1] == 7) {
					macaddr_idx = idx + 3;
					/* found MAC Address tuple */
					break;
				}
			}
		}
		if (idx < max) {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				cis_buf[macaddr_idx], cis_buf[macaddr_idx + 1],
				cis_buf[macaddr_idx + 2], cis_buf[macaddr_idx + 3],
				cis_buf[macaddr_idx + 4], cis_buf[macaddr_idx + 5]);
			DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n"));
		} else {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				mac->octet[0], mac->octet[1], mac->octet[2],
				mac->octet[3], mac->octet[4], mac->octet[5]);
			DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP,"
				" Check module mac by initial value: " MACDBG "\n",
				__FUNCTION__, MAC2STRDBG(mac->octet)));
		}
	}

	fp_mac = filp_open(macfilepath, O_RDONLY, 0);
	if (!IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n"));
		kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
		filp_close(fp_mac, NULL);

		if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
			DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n"));
			dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
		}
	}

	return ret;
}
int dhd_check_module_cid(dhd_pub_t *dhd)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	const char *cidfilepath = CIDINFO;
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	int idx, max;
	vid_info_t *cur_info;
	unsigned char *vid_start = NULL;
	unsigned char vid_length = 0;
#ifdef SUPPORT_MULTIPLE_BOARDTYPE
	board_info_t *cur_b_info = NULL;
	board_info_t *vendor_b_info = NULL;
	unsigned char *btype_start;
	unsigned char boardtype_len = 0;
#endif /* SUPPORT_MULTIPLE_BOARDTYPE */
	unsigned char cid_info[MAX_VNAME_LEN + MAX_BNAME_LEN];
	bool found = FALSE;
#if defined(BCM4334_CHIP) || defined(BCM4335_CHIP)
	const char *revfilepath = REVINFO;
#ifdef BCM4334_CHIP
	int flag_b3;
#else
	char rev_str[10] = {0};
#endif /* BCM4334_CHIP */
#endif /* BCM4334_CHIP || BCM4335_CHIP */

	/* Try reading out from CIS */
	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_INFO(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	DHD_ERROR(("[WIFI_SEC] %s: CIS reading success, ret=%d\n",
		__FUNCTION__, ret));
#ifdef DUMP_CIS
	dhd_dump_cis(cis_buf, 48);
#endif
	max = sizeof(cis_buf);
	idx = find_tuple_from_otp(cis_buf, max, CIS_TUPLE_TAG_VENDOR, &vid_length);
	if (idx > 0) {
		found = TRUE;
		vid_start = &cis_buf[idx];
	}

	if (found) {
		max = sizeof(vid_info) / sizeof(vid_info_t);
		for (idx = 0; idx < max; idx++) {
			cur_info = &vid_info[idx];
#if defined(BCM4358_CHIP)
			if (cur_info->vid_length  == 6 && vid_length == 6) {
				if (cur_info->vid[0] == vid_start[0] &&
				    cur_info->vid[3] == vid_start[3] &&
				    cur_info->vid[4] == vid_start[4])
				goto check_board_type;
			}
#endif /* BCM4358_CHIP */
			if ((cur_info->vid_length == vid_length) &&
				(cur_info->vid_length != 0) &&
				(memcmp(cur_info->vid, vid_start, cur_info->vid_length - 1) == 0))
				goto check_board_type;
		}
	}

	/* find default nvram, if exist */
	DHD_ERROR(("[WIFI_SEC] %s: cannot find CIS TUPLE set as default\n", __FUNCTION__));
	max = sizeof(vid_info) / sizeof(vid_info_t);
	for (idx = 0; idx < max; idx++) {
		cur_info = &vid_info[idx];
		if (cur_info->vid_length == 0)
			goto write_cid;
	}
	DHD_ERROR(("[WIFI_SEC] %s: cannot find default CID\n", __FUNCTION__));
	return -1;

check_board_type:
#ifdef SUPPORT_MULTIPLE_BOARDTYPE
	max = sizeof(cis_buf) - 4;
	for (idx = 0; idx < max; idx++) {
		if (cis_buf[idx] == CIS_TUPLE_TAG_START &&
			cis_buf[idx + 2] == CIS_TUPLE_TAG_BOARDTYPE) {
			boardtype_len = cis_buf[idx + 1];
			btype_start = &cis_buf[idx + 3];

			/* Check buffer overflow */
			if (&cis_buf[idx + 1] + boardtype_len
				<= &cis_buf[CIS_BUF_SIZE - 1]) {
				DHD_INFO(("[WIFI_SEC] %s: board type found.\n",
					__FUNCTION__));
				break;
			} else {
				boardtype_len = 0;
			}
		}
	}

	if (strcmp(cur_info->vname, "semco") == 0) {
		vendor_b_info = semco_board_info;
		max = sizeof(semco_board_info) / sizeof(board_info_t);
	} else if (strcmp(cur_info->vname, "murata") == 0) {
		vendor_b_info = murata_board_info;
		max = sizeof(murata_board_info) / sizeof(board_info_t);
	} else {
		max = 0;
	}

	if (boardtype_len) {
		for (idx = 0; idx < max; idx++) {
			cur_b_info = vendor_b_info;
			if ((cur_b_info->b_len == boardtype_len) &&
					(cur_b_info->b_len != 0) &&
					(memcmp(cur_b_info->btype, btype_start,
					cur_b_info->b_len - 1) == 0)) {
				DHD_INFO(("[WIFI_SEC] %s : board type name : %s\n",
					__FUNCTION__, cur_b_info->bname));
				break;
			}
			cur_b_info = NULL;
			vendor_b_info++;
		}
	}
#endif /* SUPPORT_MULTIPLE_BOARDTYPE */

write_cid:
#ifdef SUPPORT_MULTIPLE_BOARDTYPE
	if (cur_b_info && cur_b_info->b_len > 0) {
		strcpy(cid_info, cur_info->vname);
		strcpy(cid_info + strlen(cur_info->vname), cur_b_info->bname);
	} else
#endif /* SUPPORT_MULTIPLE_BOARDTYPE */
	strcpy(cid_info, cur_info->vname);

	DHD_ERROR(("[WIFI_SEC] CIS MATCH FOUND : %s\n", cid_info));
	dhd_write_cid_file(cidfilepath, cid_info, strlen(cid_info)+1);

#if defined(BCM4334_CHIP)
	/* Try reading out from OTP to distinguish B2 or B3 */
	memset(cis_buf, 0, sizeof(cis_buf));
	cish = (cis_rw_t *)&cis_buf[8];

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "otpdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_ERROR(("[WIFI_SEC] %s: OTP reading failed, err=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	/* otp 33th character is identifier for 4334B3 */
	cis_buf[34] = '\0';
	flag_b3 = bcm_atoi(&cis_buf[33]);
	if (flag_b3 & 0x1) {
		DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4334B3, %c\n", cis_buf[33]));
		dhd_write_cid_file(revfilepath, "4334B3", 6);
	}
#endif /* BCM4334_CHIP */
#if defined(BCM4335_CHIP)
	DHD_TRACE(("[WIFI_SEC] %s: BCM4335 Multiple Revision Check\n", __FUNCTION__));
	if (concate_revision(dhd->bus, rev_str, rev_str) < 0) {
		DHD_ERROR(("[WIFI_SEC] %s: fail to concate revision\n", __FUNCTION__));
		ret = -1;
	} else {
		if (strstr(rev_str, "_a0")) {
			DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4335A0\n"));
			dhd_write_cid_file(revfilepath, "BCM4335A0", 9);
		} else {
			DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4335B0\n"));
			dhd_write_cid_file(revfilepath, "BCM4335B0", 9);
		}
	}
#endif /* BCM4335_CHIP */

	return ret;
}
int dhd_check_module_vid(void *bus, osl_t *osh)
{
	uint8 *cis_buf;
	int ret = BCME_ERROR;
	int idx, max;
	vid_info_t *cur_info;
	unsigned char *vid_start;
	unsigned char vid_length;
	int found = 0;

	/*                                                                      */
	DHD_ERROR(("%s: module_vendor_id : %s, try_cnt_to_read_vid : %d\n",
		__func__, module_vendor_id, try_cnt_to_read_vid));
	if(strlen(module_vendor_id) > 0 || try_cnt_to_read_vid < 0)
	{
		DHD_ERROR(("%s: module_vendor_id : %s, try_cnt_to_read_vid : %d, SKIP\n",
			__func__, module_vendor_id, try_cnt_to_read_vid));
		return 0;
	}
	try_cnt_to_read_vid--;
	/*                                                                      */

	if (!(cis_buf = MALLOC(osh, CIS_BUF_SIZE))) {
		DHD_ERROR(("%s: cis_buf malloc failed\n", __func__));
		ret = BCME_NOMEM;
		return ret;
	}

	if ((ret = dhdsdio_cis_read((void *)bus, 0, cis_buf, CIS_BUF_SIZE)) != BCME_OK) {
		MFREE(osh, cis_buf, CIS_BUF_SIZE);
		return ret;
	}

	 max = CIS_BUF_SIZE -4;

#ifdef DUMP_CIS
	dhd_dump_cis(cis_buf, max);
#endif

	for (idx = 0; idx < max; idx++) {
		if (cis_buf[idx] == CIS_TUPLE_START) {
			if (cis_buf[idx + 2] == CIS_TUPLE_VENDOR) {
				vid_length = cis_buf[idx + 1];
				vid_start = &cis_buf[idx + 3];
				/*                 */
				break;
			} else {
				/*                                                    */
				idx += (cis_buf[idx + 1] + 1);
			}
		}
	}

	if (idx < max) {
		max = sizeof(vid_info) / sizeof(vid_info_t);
		for (idx = 0; idx < max; idx++) {
			cur_info = &vid_info[idx];
			if ((cur_info->vid_length == vid_length) &&
				(cur_info->vid_length != 0) &&
				(memcmp(cur_info->vid, vid_start + cur_info->skip, cur_info->vid_length - cur_info->skip - 1) == 0))
				{
					DHD_ERROR(("Module VID FOUND : %s\n", cur_info->vname));
					found = 1;
				}
		}
	}

	if(found)
		strncpy(module_vendor_id, cur_info->vname, MAX_VNAME_LEN);
	else
		DHD_ERROR(("Module VID NOT FOUND\n"));

	/*                                                                      */
	if(!strncmp(module_vendor_id, "murata", 6))
	{
#ifdef CONFIG_BCMDHD_MURATA_NVRAM_PATH
		strncpy(nvram_path, CONFIG_BCMDHD_MURATA_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
#else
		nvram_path[0] = '\0';
#endif
	}
	else if(!strncmp(module_vendor_id, "lgit", 4))
	{
#ifdef CONFIG_BCMDHD_LGIT_NVRAM_PATH
		strncpy(nvram_path, CONFIG_BCMDHD_LGIT_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
#else
		nvram_path[0] = '\0';
#endif
	}
	else
	{
#ifdef CONFIG_BCMDHD_DEFAULT_NVRAM_PATH
		strncpy(nvram_path, CONFIG_BCMDHD_DEFAULT_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
#else
		nvram_path[0] = '\0';
#endif
	}

	DHD_ERROR(("Final nvram_path: %s\n", nvram_path));

	/*                                                                      */
	MFREE(osh, cis_buf, CIS_BUF_SIZE);
	return ret;

}