Exemple #1
0
/*
 * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2
 *
 */
static int
wl_android_set_mac_address_filter(struct net_device *dev, const char* str)
{
	int i;
	int ret = 0;
	int macnum = 0;
	int macmode = MACLIST_MODE_DISABLED;
	struct maclist *list;
	char eabuf[ETHER_ADDR_STR_LEN];

	/* string should look like below (macmode/macnum/maclist) */
	/*   1 2 00:11:22:33:44:55 00:11:22:33:44:ff  */

	/* get the MAC filter mode */
	macmode = bcm_atoi(strsep((char**)&str, " "));

	if (macmode < MACLIST_MODE_DISABLED || macmode > MACLIST_MODE_ALLOW) {
		DHD_ERROR(("%s : invalid macmode %d\n", __FUNCTION__, macmode));
		return -1;
	}

	macnum = bcm_atoi(strsep((char**)&str, " "));
	if (macnum < 0 || macnum > MAX_NUM_MAC_FILT) {
		DHD_ERROR(("%s : invalid number of MAC address entries %d\n",
			__FUNCTION__, macnum));
		return -1;
	}
	/* allocate memory for the MAC list */
	list = (struct maclist*)kmalloc(sizeof(int) +
		sizeof(struct ether_addr) * macnum, GFP_KERNEL);
	if (!list) {
		DHD_ERROR(("%s : failed to allocate memory\n", __FUNCTION__));
		return -1;
	}
	/* prepare the MAC list */
	list->count = htod32(macnum);
	bzero((char *)eabuf, ETHER_ADDR_STR_LEN);
	for (i = 0; i < list->count; i++) {
		strncpy(eabuf, strsep((char**)&str, " "), ETHER_ADDR_STR_LEN - 1);
		if (!(ret = bcm_ether_atoe(eabuf, &list->ea[i]))) {
			DHD_ERROR(("%s : mac parsing err index=%d, addr=%s\n",
				__FUNCTION__, i, eabuf));
			list->count--;
			break;
		}
		DHD_INFO(("%s : %d/%d MACADDR=%s", __FUNCTION__, i, list->count, eabuf));
	}
	/* set the list */
	if ((ret = wl_android_set_ap_mac_list(dev, macmode, list)) != 0)
		DHD_ERROR(("%s : Setting MAC list failed error=%d\n", __FUNCTION__, ret));

	kfree(list);

	return 0;
}
void dhd_get_memdump_info(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	uint32 mem_val = 0;
	int ret = 0;
	char *filepath = MEMDUMPINFO;

	/* Read memdump info from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
		goto done;
	} else {
		ret = kernel_read(fp, 0, (char *)&mem_val, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			goto done;
		}

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

		DHD_ERROR(("[WIFI_SEC]%s: MEMDUMP ENABLED = %d\n", __FUNCTION__, mem_val));
		filp_close(fp, NULL);
	}

done:
	dhd->memdump_enabled = (mem_val < DUMP_MEMFILE_MAX) ? mem_val : DUMP_DISABLED;
}
Exemple #3
0
int dhd_customer_set_country(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	char *filepath = "/data/.ccode.info";
	char iovbuf[WL_EVENTING_MASK_LEN + 12] = {0};
	char buffer[10] = {0};
	int ret = 0;
	wl_country_t cspec;
	int buf_len = 0;
	char country_code[WLC_CNTRY_BUF_SZ];
	int country_rev;
	int country_offset;
	int country_code_size;
	char country_rev_buf[WLC_CNTRY_BUF_SZ];
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("%s: %s open failed\n", __FUNCTION__, filepath));
		return -1;
	} else {
		if (kernel_read(fp, 0, buffer, sizeof(buffer))) {
			memset(&cspec, 0, sizeof(cspec));
			memset(country_code, 0, sizeof(country_code));
			memset(country_rev_buf, 0, sizeof(country_rev_buf));
			country_offset = strcspn(buffer, " ");
			country_code_size = country_offset;
			if (country_offset != 0) {
				strncpy(country_code, buffer, country_offset);
				strncpy(country_rev_buf, buffer+country_offset+1, strlen(buffer) - country_code_size + 1);
				country_rev = bcm_atoi(country_rev_buf);
				buf_len = bcm_mkiovar("country", (char *)&cspec, sizeof(cspec), iovbuf, sizeof(iovbuf));
				ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, buf_len, FALSE, 0);
				memcpy((void *)&cspec, iovbuf, sizeof(cspec));
				if (!ret) {
					DHD_ERROR(("%s: get country ccode:%s country_abrev:%s rev:%d  \n", __FUNCTION__, cspec.ccode, cspec.country_abbrev, cspec.rev));
					if ((strncmp(country_code, cspec.ccode, WLC_CNTRY_BUF_SZ) != 0) || (cspec.rev != country_rev)) {
						strncpy(cspec.country_abbrev, country_code, country_code_size);
						strncpy(cspec.ccode, country_code, country_code_size);
						cspec.rev = country_rev;
						DHD_ERROR(("%s: set country ccode:%s country_abrev:%s rev:%d  \n", __FUNCTION__, cspec.ccode, cspec.country_abbrev, cspec.rev));
						buf_len = bcm_mkiovar("country", (char *)&cspec, sizeof(cspec), iovbuf, sizeof(iovbuf));
						ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, buf_len, TRUE, 0);
					}
				}
			} else {
				DHD_ERROR(("%s: set country %s failed code \n", __FUNCTION__, country_code));
				ret = -1;
			}
		} else {
			DHD_ERROR(("%s: Reading from the '%s' returns 0 bytes \n", __FUNCTION__, filepath));
			ret = -1;
		}
	}
	if (fp)
		filp_close(fp, NULL);

	return ret;
}
Exemple #4
0
static int
wl_android_set_max_num_sta(struct net_device *dev, const char* string_num)
{
	int max_assoc;

	max_assoc = bcm_atoi(string_num);
	DHD_INFO(("%s : HAPD_MAX_NUM_STA = %d\n", __FUNCTION__, max_assoc));
	wldev_iovar_setint(dev, "maxassoc", max_assoc);
	return 1;
}
int dhd_sel_ant_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 ant_val = 0;
	char *filepath = "/data/.ant.info";
	char iovbuf[WLC_IOCTL_SMLEN];

	/* Read antenna settings from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI] %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] %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] %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] %s: Invalid value %d read from the file %s\n",
				__FUNCTION__, ant_val, filepath));
			return -1;
		}
	}

	/* 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] %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] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	return 0;
}
Exemple #6
0
static int
wl_android_set_hide_ssid(struct net_device *dev, const char* string_num)
{
	int hide_ssid;
	int enable = 0;

	hide_ssid = bcm_atoi(string_num);
	DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__, hide_ssid));
	if (hide_ssid)
		enable = 1;
	wldev_iovar_setint(dev, "closednet", enable);
	return 1;
}
/*
 * RSDBOFFINFO = /data/.rsdb.info
 *  - rsdb_mode = 1            => Don't change RSDB mode / RSDB stay as turn on
 *  - rsdb_mode = 0            => Trun Off RSDB mode
 *  - file not exist          => Don't change RSDB mode / RSDB stay as turn on
 */
int dhd_rsdb_mode_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 rsdb_mode = 0;
	char *filepath = RSDBINFO;
	char iovbuf[WLC_IOCTL_SMLEN];

	/* Read RSDB on/off request from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
		return ret;
	} else {
		ret = kernel_read(fp, 0, (char *)&rsdb_mode, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			return ret;
		}

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

		DHD_ERROR(("[WIFI_SEC] %s: RSDB mode from file = %d\n", __FUNCTION__, rsdb_mode));
		filp_close(fp, NULL);

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

	if (rsdb_mode == 0) {
		bcm_mkiovar("rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode),
			iovbuf, sizeof(iovbuf));

		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
				iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: rsdb_mode ret= %d\n", __FUNCTION__, ret));
		} else {
			DHD_ERROR(("[WIFI_SEC] %s: rsdb_mode to MIMO(RSDB OFF) succeeded\n",
				__FUNCTION__));
		}
	}

	return ret;
}
Exemple #8
0
/* CMD_AMPDU_MPDU */
static int
wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num)
{
	int err = 0;
	int ampdu_mpdu;

	ampdu_mpdu = bcm_atoi(string_num);

	if (ampdu_mpdu > 32) {
		DHD_ERROR(("%s : ampdu_mpdu MAX value is 32.\n", __FUNCTION__));
		return -1;
	}
	DHD_ERROR(("%s : ampdu_mpdu = %d\n", __FUNCTION__, ampdu_mpdu));
	err = wldev_iovar_setint(dev, "ampdu_mpdu", ampdu_mpdu);
	if (err < 0) {
		DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__, err));
		return -1;
	}

	return 0;
}
int
BCMINITFN(nvram_resetgpio_init)(void *si)
{
	char *value;
	int gpio;
	si_t *sih;

	sih = (si_t *)si;

	value = nvram_get("reset_gpio");
	if (!value)
		return -1;

	gpio = (int) bcm_atoi(value);
	if (gpio > 7)
		return -1;

	/* Setup GPIO input */
	si_gpioouten(sih, ((uint32) 1 << gpio), 0, GPIO_DRV_PRIORITY);

	return gpio;
}
static bool
nvram_reset(void *sbh)
{
	chipcregs_t *cc;
	char *value;
	uint32 watchdog = 0, gpio;
	uint idx, msec;

	idx = sb_coreidx(sbh);

	/* Check if we were soft reset */
	if ((cc = sb_setcore(sbh, SB_CC, 0))) {
		watchdog = R_REG(&cc->intstatus) & 0x80000000;
		sb_setcoreidx(sbh, idx);
	}
	if (watchdog)
		return FALSE;

	value = nvram_get("reset_gpio");
	if (!value)
		return FALSE;

	gpio = (uint32) bcm_atoi(value);
	if (gpio > 7)
		return FALSE;

	/* Setup GPIO input */
	sb_gpioouten(sbh, (1 << gpio), 0);

	/* GPIO reset is asserted low */
	for (msec = 0; msec < 5000; msec++) {
		if (sb_gpioin(sbh) & (1 << gpio))
			return FALSE;
		OSL_DELAY(1000);
	}

	return TRUE;
}
/*
 * LOGTRACEINFO = /data/.logtrace.info
 *  - logtrace = 1            => Enable LOGTRACE Event
 *  - logtrace = 0            => Disable LOGTRACE Event
 *  - file not exist          => Disable LOGTRACE Event
 */
int dhd_logtrace_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 logtrace = 0;
	char *filepath = LOGTRACEINFO;

	/* Read LOGTRACE Event on/off request from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
		return 0;
	} else {
		ret = kernel_read(fp, 0, (char *)&logtrace, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			return 0;
		}

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

		DHD_ERROR(("[WIFI_SEC] %s: LOGTRACE On/Off from file = %d\n",
			__FUNCTION__, logtrace));
		filp_close(fp, NULL);

		/* Check value from the file */
		if (logtrace > 2) {
			DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
				__FUNCTION__, logtrace, filepath));
			return 0;
		}
	}

	return (int)logtrace;
}
Exemple #12
0
void __init prom_init(int argc, const char **arg)
{
        int	hasBootParms = 0;
        char msg[500];
	 char pmon_kargs[CL_SIZE];
		
	uart_init(27000000);
//uart_puts("Inside prom_init\r\n");

	/* Fill in platform information */
	mips_machgroup = MACH_GROUP_BRCM;
	mips_machtype  = MACH_BCM93730;

	/* Boot arguments can be put here */
	/* Browse memory region to see if the boot rom deposits an argument there */
	{
		unsigned long sigAddr = KSEG1ADDR(LOAD_ADDRESS - BOOT_OPT_SIZE);
		unsigned long mapAddr = (sigAddr & 0xFFFFF000);
		unsigned long offset = sigAddr - mapAddr;
		char* pMap;
		char*	p;   /* Start address of bootParms including signature */

		char*	pBootParms; /* Actual start address of bootParms */
		int len = 0;
		int* plen;

//uart_puts( "Before ioremap\n");
		//pMap = ioremap_nocache(mapAddr, 4096);
		pMap = (char*) mapAddr;
		p = &pMap[offset];
//uart_puts("After ioremap\n");
#ifdef DEBUG_PROM
		sprintf(msg,"prom_init, mapped address %08lx at %08lx, pSig1=%08lx, sigAddr=%08lx\n",
			mapAddr, (unsigned long) pMap, (unsigned long) p, sigAddr);
		uart_puts(msg);
		printBootArgRegion(p);
#endif
		if (0 == memcmp(p, BOOT_OPT_SIG, 1+strlen(BOOT_OPT_SIG))) {
			len += BOOT_OPT_LEN_OFFSET;

			/* Rely on BOOT_OPT_LEN_OFFSET to place it at boundary */
			plen = (int*) &p[len];
			pBootParms = &p[len + sizeof(int)];
			/* Making sure that we don't run over any bounds as there is no guarantee
			 * that COMMAND_LINE_SIZE <= BOOT_OPT_SIZE minus the sig
			 */
			if (*plen <= COMMAND_LINE_SIZE && *plen <= (BOOT_OPT_SIZE - 2*BOOT_OPT_LEN_OFFSET)) {
				len += *plen + sizeof(int);
				if (0 == memcmp(&p[len], BOOT_OPT_SIG, 1+strlen(BOOT_OPT_SIG))) {
					hasBootParms = 1;

					printBootArgRegion(p); /* Force it to include the next line in the log */
					sprintf(msg, "Found bootargs=<%s>,%d bytes\n", pBootParms, *plen);
					uart_puts(msg);
					strncpy(pmon_kargs, pBootParms, *plen);

					/* Wipe out boot parameter, so that subsequent reboot would not have it */
					memset(p, 0, 1+strlen(BOOT_OPT_SIG) + *plen);
				}
				else {
					sprintf(msg, "2nd Signature do not match @%08x, ignoring kernel boot parameters\n", &p[len]);
					uart_puts(msg);
					printBootArgRegion(p);
				}
			}
			else {

				sprintf(msg, "Length %d of kernel parameter is larger than allowed min(%d,%d)\n",
					*plen, COMMAND_LINE_SIZE, (BOOT_OPT_SIZE - 2*BOOT_OPT_LEN_OFFSET));
				uart_puts(msg);	

				printBootArgRegion(p);
     		      }
		}
		else {

			printk(KERN_INFO "1st Signature do not match, ignoring kernel boot parameters\n");
			printBootArgRegion(p);

		}
    }
	/* Use default if we don't see a valid boot prom */
	/* We may use a more sophisticated scheme in filling out the parameters later, but for now
	 * just require that the boot loader procedure must provide the full command.  Ugly but
	 * better than nothing.
	 */
	if (hasBootParms && isRootSpecified(pmon_kargs)) {
		strcpy(arcs_cmdline, pmon_kargs);
	   	appendConsoleArg(arcs_cmdline);
	}
	else {
	/* Kernel default arguments */

#ifdef CONFIG_BLK_DEV_INITRD
	         strcpy(arcs_cmdline, "rw console=ttyS0,115200");

#elif defined(CONFIG_CMDLINE)
		char* p;
		char msg[256];

		strcpy(arcs_cmdline, CONFIG_CMDLINE);
		sprintf(msg, "Default command line = \'%s\'\n", CONFIG_CMDLINE);
		uart_puts(msg);
		p = &arcs_cmdline[0];
		while (p != NULL && *p != '\0') {
			if (!isspace(*p))
				break;
			p++;
		}
		if (p == NULL || *p == '\0') {
		sprintf(msg, "Defaulting to boot from HD\n", CONFIG_CMDLINE);
		uart_puts(msg);
			/* Default is to boot from HD */
			strcpy(arcs_cmdline,
				"root=/dev/hda1 rw console=tty0 console=ttyS0,115200");
		}
		else {
			/* Make sure that the boot params specify a console */
			appendConsoleArg(arcs_cmdline);
		}
#else /* No CONFIG_CMDLINE, and not Initrd */
		/* Default is to boot from HD */
		strcpy(arcs_cmdline,
			"root=/dev/hda1 rw console=tty0 console=ttyS0,115200");
#endif /* No CONFIG_CMDLINE */

		/*
		 * if root= is not on the command line, but user specified something else, tag it on
		 */
		if (hasBootParms && !isRootSpecified(pmon_kargs)) {
			strcat(arcs_cmdline, " ");
			strcat(arcs_cmdline, pmon_kargs);
        	}
	} /* End else no root= option is specified */
	uart_puts("Kernel boot options: ");
	uart_puts(arcs_cmdline);
	uart_puts("\r\n");

	{
		/*
		  * Support  mem=nn[KMG] on command line
		  */
		const char* p = (const char*) arcs_cmdline;
		const char* q = NULL;
		const char* sizep = NULL;
		int i, foundKeyword = 0, foundNumber = 0, foundUnit = 0, done = 0;
		unsigned int size = 0, unitShift = 0;
		unsigned int ramSizeMB;

		for (i = 0; i < strlen(p) - 6 && !done; i++) {
//sprintf(msg, "i=%d\n", i);
//uart_puts(msg);
			if (0 == strncmp(&p[i], "mem=", 4)) {
				/* Found key, now read in value */
				foundKeyword = 1;

//uart_puts("while\n");
				for (sizep = q = &p[i+4];*q != '\0' && !done; q++) {
					if (isdigit(*q)) {
						foundNumber = 1;
						continue;
					}

					if (foundNumber) {
//uart_puts("found number\n");

						switch (*q) {
						case 'k':
						case 'K':
							unitShift = 10; /* KB shift value*/
							foundUnit = 1;
							done = 1;
							break;
						case 'm':
						case 'M':
							unitShift = 20; /* MB shift value */
							foundUnit = 1;
							done = 1;
//uart_puts("found unit M\n");
//sprintf(msg, "q=%x\n", q);
//uart_puts(msg);

							break;
						case 'g':
						case 'G':
							/* Probably too big */
							unitShift = 30; /* GB shift value */
							foundUnit = 1;
							done = 1;
							break;
						default:
							done = 1;
							break;
						} 
					}
				}
			} 
		} 

		if (foundNumber) {
			if (foundUnit) {
//uart_puts("Size=");
//uart_puts(sizep);
//uart_puts("\n");
				size = bcm_atoi(sizep);
//sprintf(msg, "q=%x\n", q);
//uart_puts(msg);

				sprintf(msg, "Using %d %cB for memory\n", size, *(q-1));
				uart_puts(msg);
			}
			else {
				uart_puts("Syntax: mem=nn[KMG] Option ignored : No unit specified\n");
			}
		}
		else if (foundKeyword) {
			uart_puts("Syntax: mem=nn[KMG] Option ignored : No size specified\n");
		}

		g_board_RAM_size = get_RAM_size();
		ramSizeMB = g_board_RAM_size >> 20;

		{
			/* 
			  * Kernels on STBs with larger than 32MB, we only use 32MB RAM for the kernel
			  */

	  		if (foundNumber && foundUnit) {
				if (size <= ramSizeMB && size > 0) {
				/* Already output size above */
				} 
				else {
					uart_puts("Invalid size ignored, using default value of 32MB\n");
					size = 32;
					unitShift = 20;
				}
			}
			/* No mem=xxU specified, give the kernel 32MB of memory */
			else {
				uart_puts("Using 32MB for memory, overwrite by passing mem=xx\n");
				size = 32;
				unitShift = 20;
			}
		}
		
		/* Assert size and unit not 0 */
		add_memory_region(0, size << unitShift, BOOT_MEM_RAM);

		/* Register the reserved upper memory, in order to allow kernel to cache them */
		if (size < ramSizeMB) {
			add_memory_region(size << unitShift, (ramSizeMB-size) << unitShift, BOOT_MEM_RAM);
		}
	
	}
}
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;
}
int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val)
{
	struct file *fp = NULL;
	char *filepath = NULL;
	int val = 0;

	if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
		(mode >= PARAM_LAST_VALUE)) {
		DHD_ERROR(("[WIFI_SEC] %s: invalid argument\n", __FUNCTION__));
		return BCME_ERROR;
	}

	switch (mode) {
		case SET_PARAM_BUS_TXGLOM_MODE:
			filepath = "/data/.bustxglom.info";
			break;
		case SET_PARAM_ROAMOFF:
			filepath = "/data/.roamoff.info";
			break;
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
			filepath = "/data/.frameburst.info";
			break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
			filepath = "/data/.txbf.info";
			break;
#endif /* USE_WL_TXBF */
#ifdef PROP_TXSTATUS
		case SET_PARAM_PROPTX:
			filepath = "/data/.proptx.info";
			break;
#endif /* PROP_TXSTATUS */
		default:
			DHD_ERROR(("[WIFI_SEC] %s: File to find file name for index=%d\n",
				__FUNCTION__, mode));
			return BCME_ERROR;
	}

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist \n",
			__FUNCTION__, filepath));
		return BCME_ERROR;
	} else {
		if (kernel_read(fp, fp->f_pos, (char *)&val, 4) < 0) {
			filp_close(fp, NULL);
			/* File operation is failed so we will return error code */
			DHD_ERROR(("[WIFI_SEC] %s: read failed, file path=%s\n",
				__FUNCTION__, filepath));
			return BCME_ERROR;
		}
		filp_close(fp, NULL);
	}

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

	switch (mode) {
		case SET_PARAM_ROAMOFF:
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
#endif /* USE_WL_TXBF */
#ifdef PROP_TXSTATUS
		case SET_PARAM_PROPTX:
#endif /* PROP_TXSTATUS */
		if (val < 0 || val > 1) {
			DHD_ERROR(("[WIFI_SEC] %s: value[%d] is out of range\n",
				__FUNCTION__, *read_val));
			return BCME_ERROR;
		}
			break;
		default:
			return BCME_ERROR;
	}
	*read_val = (uint)val;
	return BCME_OK;
}
Exemple #15
0
static int
wl_android_set_auto_channel(struct net_device *dev, const char* string_num,
	char* command, int total_len)
{
	int channel;
	int chosen = 0;
	int retry = 0;
	int ret = 0;

	/* Restrict channel to 1 - 7: 2GHz, 20MHz BW, No SB */
	u32 req_buf[8] = {7, 0x2B01, 0x2B02, 0x2B03, 0x2B04, 0x2B05, 0x2B06,
		0x2B07};

	/* Auto channel select */
	wl_uint32_list_t request;

	channel = bcm_atoi(string_num);
	DHD_INFO(("%s : HAPD_AUTO_CHANNEL = %d\n", __FUNCTION__, channel));

	if (channel == 20)
		ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&req_buf,
			sizeof(req_buf), true);
	else { /* channel == 0 */
		request.count = htod32(0);
		ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&request,
			sizeof(request), true);
	}

	if (ret < 0) {
		DHD_ERROR(("%s: can't start auto channel scan, err = %d\n",
			__FUNCTION__, ret));
		channel = 0;
		goto done;
	}

	/* Wait for auto channel selection, max 2500 ms */
	bcm_mdelay(500);

	retry = 10;
	while (retry--) {
		ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen),
			false);
		if (ret < 0 || dtoh32(chosen) == 0) {
			DHD_INFO(("%s: %d tried, ret = %d, chosen = %d\n",
				__FUNCTION__, (10 - retry), ret, chosen));
			bcm_mdelay(200);
		}
		else {
			channel = (u16)chosen & 0x00FF;
			DHD_ERROR(("%s: selected channel = %d\n", __FUNCTION__, channel));
			break;
		}
	}

	if (retry == 0) {
		DHD_ERROR(("%s: auto channel timed out, failed\n", __FUNCTION__));
		channel = 0;
	}

done:
	snprintf(command, 4, "%d", channel);
	DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));

	return 4;
}
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_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;
}
Exemple #18
0
static void *
chipattach(etc_info_t *etc, void *osh, void *regsva)
{
	struct bcm4xxx *ch;
	bcmenetregs_t *regs;
	char name[16];
	char *var;
	uint boardflags, boardtype;

	ET_TRACE(("et%d: chipattach: regsva 0x%lx\n", etc->unit, (ulong)regsva));

	if ((ch = (struct bcm4xxx *)MALLOC(osh, sizeof(struct bcm4xxx))) == NULL) {
		ET_ERROR(("et%d: chipattach: out of memory, malloced %d bytes\n", etc->unit,
		          MALLOCED(osh)));
		return (NULL);
	}
	bzero((char *)ch, sizeof(struct bcm4xxx));

	ch->etc = etc;
	ch->et = etc->et;
	ch->osh = osh;

	/* store the pointer to the sw mib */
	etc->mib = (void *)&ch->mib;

	/* get si handle */
	if ((ch->sih = si_attach(etc->deviceid, ch->osh, regsva, PCI_BUS, NULL, &ch->vars,
	                         &ch->vars_size)) == NULL) {
		ET_ERROR(("et%d: chipattach: si_attach error\n", etc->unit));
		goto fail;
	}

	/* We used to have an assert here like:
	 *	si_coreid(ch->sih) == ENET_CORE_ID
	 * but srom-less systems and simulators don't have a way to
	 * provide a default bar0window so we were relying on nvram
	 * variables. At some point we decided that we could do away
	 * with that since the wireless driver was simply doing a
	 * setcore in attach. So we need to do the same here for
	 * the ethernet.
	 */
	if ((regs = (bcmenetregs_t *)si_setcore(ch->sih, ENET_CORE_ID, etc->unit)) == NULL) {
		ET_ERROR(("et%d: chipattach: Could not setcore to the ENET core\n", etc->unit));
		goto fail;
	}

	ch->regs = regs;
	etc->chip = ch->sih->chip;
	etc->chiprev = ch->sih->chiprev;
	etc->coreid = si_coreid(ch->sih);
	etc->corerev = si_corerev(ch->sih);
	etc->nicmode = !(ch->sih->bustype == SI_BUS);
	etc->coreunit = si_coreunit(ch->sih);
	etc->boardflags = getintvar(ch->vars, "boardflags");

	etc->hwrxoff = HWRXOFF;

	boardflags = etc->boardflags;
	boardtype = ch->sih->boardtype;

	/* Backplane clock ticks per microsecs: used by gptimer, intrecvlazy */
	etc->bp_ticks_usec = si_clock(ch->sih) / 1000000;

	/* get our local ether addr */
	sprintf(name, "et%dmacaddr", etc->coreunit);
	var = getvar(ch->vars, name);
	if (var == NULL) {
		ET_ERROR(("et%d: chipattach: NVRAM_GET(%s) not found\n", etc->unit, name));
		goto fail;
	}
	bcm_ether_atoe(var, &etc->perm_etheraddr);

	if (ETHER_ISNULLADDR(&etc->perm_etheraddr)) {
		ET_ERROR(("et%d: chipattach: invalid format: %s=%s\n", etc->unit, name, var));
		goto fail;
	}
	bcopy((char *)&etc->perm_etheraddr, (char *)&etc->cur_etheraddr, ETHER_ADDR_LEN);

	/*
	 * Too much can go wrong in scanning MDC/MDIO playing "whos my phy?" .
	 * Instead, explicitly require the environment var "et<coreunit>phyaddr=<val>".
	 */

	/* get our phyaddr value */
	sprintf(name, "et%dphyaddr", etc->coreunit);
	var = getvar(ch->vars, name);
	if (var == NULL) {
		ET_ERROR(("et%d: chipattach: NVRAM_GET(%s) not found\n", etc->unit, name));
		goto fail;
	}
	etc->phyaddr = bcm_atoi(var) & EPHY_MASK;

	/* nvram says no phy is present */
	if (etc->phyaddr == EPHY_NONE) {
		ET_ERROR(("et%d: chipattach: phy not present\n", etc->unit));
		goto fail;
	}

	/* get our mdc/mdio port number */
	sprintf(name, "et%dmdcport", etc->coreunit);
	var = getvar(ch->vars, name);
	if (var == NULL) {
		ET_ERROR(("et%d: chipattach: NVRAM_GET(%s) not found\n", etc->unit, name));
		goto fail;
	}
	etc->mdcport = bcm_atoi(var);

	/* configure pci core */
	si_pci_setup(ch->sih, (1 << si_coreidx(ch->sih)));

	/* reset the enet core */
	chipreset(ch);

	/* dma attach */
	sprintf(name, "et%d", etc->coreunit);
	if ((ch->di = dma_attach(osh, name, ch->sih,
	                         (void *)&regs->dmaregs.xmt, (void *)&regs->dmaregs.rcv,
	                         NTXD, NRXD, RXBUFSZ, -1, NRXBUFPOST, HWRXOFF,
	                         &et_msg_level)) == NULL) {
		ET_ERROR(("et%d: chipattach: dma_attach failed\n", etc->unit));
		goto fail;
	}
	etc->txavail[TX_Q0] = (uint *)&ch->di->txavail;

	/* set default sofware intmask */
	ch->intmask = DEF_INTMASK;

	/*
	 * For the 5222 dual phy shared mdio contortion, our phy is
	 * on someone elses mdio pins.  This other enet enet
	 * may not yet be attached so we must defer the et_phyfind().
	 */
	/* if local phy: reset it once now */
	if (etc->mdcport == etc->coreunit)
		chipphyreset(ch, etc->phyaddr);

#ifdef ETROBO
	/*
	 * Broadcom Robo ethernet switch.
	 */
	if ((boardflags & BFL_ENETROBO) &&
	    (etc->phyaddr == EPHY_NOREG)) {
		/* Attach to the switch */
		if (!(etc->robo = bcm_robo_attach(ch->sih, ch, ch->vars,
		                                  (miird_f)bcm47xx_et_chops.phyrd,
		                                  (miiwr_f)bcm47xx_et_chops.phywr))) {
			ET_ERROR(("et%d: chipattach: robo_attach failed\n", etc->unit));
			goto fail;
		}
		/* Enable the switch and set it to a known good state */
		if (bcm_robo_enable_device(etc->robo)) {
			ET_ERROR(("et%d: chipattach: robo_enable_device failed\n", etc->unit));
			goto fail;
		}
		/* Configure the switch to do VLAN */
		if ((boardflags & BFL_ENETVLAN) &&
		    bcm_robo_config_vlan(etc->robo, etc->perm_etheraddr.octet)) {
			ET_ERROR(("et%d: chipattach: robo_config_vlan failed\n", etc->unit));
			goto fail;
		}
		/* Enable switching/forwarding */
		if (bcm_robo_enable_switch(etc->robo)) {
			ET_ERROR(("et%d: chipattach: robo_enable_switch failed\n", etc->unit));
			goto fail;
		}
	}
#endif /* ETROBO */

#ifdef ETADM
	/*
	 * ADMtek ethernet switch.
	 */
	if (boardflags & BFL_ENETADM) {
		/* Attach to the device */
		if (!(ch->adm = adm_attach(ch->sih, ch->vars))) {
			ET_ERROR(("et%d: chipattach: adm_attach failed\n", etc->unit));
			goto fail;
		}
		/* Enable the external switch and set it to a known good state */
		if (adm_enable_device(ch->adm)) {
			ET_ERROR(("et%d: chipattach: adm_enable_device failed\n", etc->unit));
			goto fail;
		}
		/* Configure the switch */
		if ((boardflags & BFL_ENETVLAN) && adm_config_vlan(ch->adm)) {
			ET_ERROR(("et%d: chipattach: adm_config_vlan failed\n", etc->unit));
			goto fail;
		}
	}
#endif /* ETADM */

	return ((void *)ch);

fail:
	chipdetach(ch);
	return (NULL);
}
int sec_get_param(dhd_pub_t *dhd, int mode)
{
	struct file *fp = NULL;
	char *filepath = NULL;
	int val, ret = 0;

	if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
		(mode >= PARAM_LAST_VALUE)) {
		DHD_ERROR(("[WIFI] %s: invalid argument\n", __FUNCTION__));
		return -EINVAL;
	}

	switch (mode) {
		case SET_PARAM_BUS_TXGLOM_MODE:
			filepath = "/data/.bustxglom.info";
			break;
		case SET_PARAM_ROAMOFF:
			filepath = "/data/.roamoff.info";
			break;
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
			filepath = "/data/.frameburst.info";
			break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
			filepath = "/data/.txbf.info";
			break;
#endif /* USE_WL_TXBF */
		default:
			return -EINVAL;
	}

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		ret = -EIO;
	} else {
		ret = kernel_read(fp, fp->f_pos, (char *)&val, 4);
		filp_close(fp, NULL);
	}

	if (ret < 0) {
		/* File operation is failed so we will return default value */
		switch (mode) {
			case SET_PARAM_BUS_TXGLOM_MODE:
				val = CUSTOM_GLOM_SETTING;
				break;
			case SET_PARAM_ROAMOFF:
#ifdef ROAM_ENABLE
				val = 0;
#elif defined(DISABLE_BUILTIN_ROAM)
				val = 1;
#else
				val = 0;
#endif /* ROAM_ENABLE */
				break;
#ifdef USE_WL_FRAMEBURST
			case SET_PARAM_FRAMEBURST:
				val = 1;
				break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
			case SET_PARAM_TXBF:
				val = 1;
				break;
#endif /* USE_WL_TXBF */
		}

		DHD_INFO(("[WIFI] %s: File open failed, file path=%s,"
			" default value=%d\n",
			__FUNCTION__, filepath, val));
		return val;
	}

	val = bcm_atoi((char *)&val);
	DHD_INFO(("[WIFI] %s: %s = %d\n", __FUNCTION__, filepath, val));

	switch (mode) {
		case SET_PARAM_ROAMOFF:
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
#endif /* USE_WL_TXBF */
			val = val ? 1 : 0;
			break;
	}

	return val;
}
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;
}
Exemple #21
0
/*
 * ethHwAddrs is an array of 16 uchar arrays, each of length 6, allocated by the caller
 * numAddrs are the actual number of HW addresses used by CFE.
 * For now we only use 1 MAC address for eth0
 */
int get_cfe_boot_parms( char bootParms[CFE_CMDLINE_BUFLEN], int* numAddrs, unsigned char* ethHwAddrs[] )
{
	/*
	 * This string can be whatever you want, as long
	 * as it is * consistant both within CFE and here.
	 */
	const char* cfe_env = "BOOT_FLAGS";
	const char* eth0HwAddr_env = "ETH0_HWADDR";
	cfe_xiocb_t cfeparam;
	int res;

	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,   strlen(cfe_env),
				   (void *)bootParms, CFE_CMDLINE_BUFLEN);

	if (res)
		res = -1;
	else {
		/* The kernel only takes 256 bytes, but CFE buffer can get up to 1024 bytes */
		if (strlen(bootParms) >= COMMAND_LINE_SIZE) {
			int i;
			for (i = COMMAND_LINE_SIZE-1; i >= 0; i--) {
				if (isspace(bootParms[i])) {
					bootParms[i] = '\0';
					break;
				}
			}
		}	
	}

	if (ethHwAddrs != NULL) {
		unsigned char eth0HwAddr[ETH_HWADDR_LEN];
		int i, j, k;

		*numAddrs = 1;

		res = get_cfe_env_variable(&cfeparam,
					   (void *)eth0HwAddr_env, strlen(eth0HwAddr_env),
					   (void *)eth0HwAddr,     ETH_HWADDR_LEN*(*numAddrs));
		if (res)
			res = -2;
		else {
			if (strlen(eth0HwAddr) >= ETH_HWADDR_LEN*(*numAddrs))
				eth0HwAddr[ETH_HWADDR_LEN-1] = '\0';

			/*
			 * Convert to binary format
			 */
			for (k = 0; k < *numAddrs; k++) {
				unsigned char* hwAddr = ethHwAddrs[k];
				int done = 0;
				for (i = 0,j = 0; i < ETH_HWADDR_LEN && !done; ) {
					switch (eth0HwAddr[i]) {
					case ':':
						i++;
						continue;
				
					case '\0':
						done = 1;
						break;

					default:
						hwAddr[j] = (unsigned char) ((hex(eth0HwAddr[i]) << 4) | hex(eth0HwAddr[i+1]));
						j++;
						i +=2;
					}
				}
			}
			res = 0;
		}
	}

#if defined (CONFIG_MIPS_BCM_NDVD)
	/*
	 * Kernel tunables exported to the user
	 * via CFE Environment variables:
	 *
	 *  int ATAPI_ERRINFO   = -1;   {0, 1}
	 *  int NO_EARLY_SPINUP = -1;   {0, 1)
	 */
	cfe_env = "ATAPI_ERRINFO";
	tmp_envbuf[0] = 0;
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,    strlen(cfe_env),
				   (void *)tmp_envbuf, sizeof(tmp_envbuf));
	if (res == 0 && tmp_envbuf[0])
		ATAPI_ERRINFO = bcm_atoi(tmp_envbuf);
	else if (res)
		res = -3;

	cfe_env = "NO_EARLY_SPINUP";
	tmp_envbuf[0] = 0;
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,    strlen(cfe_env),
				   (void *)tmp_envbuf, sizeof(tmp_envbuf));
	if (res == 0 && tmp_envbuf[0])
		NO_EARLY_SPINUP = bcm_atoi(tmp_envbuf);
	else if (res)
		res = -3;


	/*
	 * Kernel tunables exported to the user
	 * via CFE Environment variables:
	 *
	 *  int SATA_RX_LVL   = -1;   {0..3}
	 *  int SATA_TX_LVL   = -1;   {0..15}
	 *  int SATA_TX_PRE   = -1;   {0..7}
	 *
	 *  int USB_IPP       = -1;   {0, 1}
	 */
	cfe_env = "SATA_RX_LVL";
	tmp_envbuf[0] = 0;
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,    strlen(cfe_env),
				   (void *)tmp_envbuf, sizeof(tmp_envbuf));
	if (res == 0 && tmp_envbuf[0])
		SATA_RX_LVL = bcm_atoi(tmp_envbuf);
	else if (res)
		res = -3;

	cfe_env = "SATA_TX_LVL";
	tmp_envbuf[0] = 0;
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,    strlen(cfe_env),
				   (void *)tmp_envbuf, sizeof(tmp_envbuf));
	if (res == 0 && tmp_envbuf[0])
		SATA_TX_LVL = bcm_atoi(tmp_envbuf);
	else if (res)
		res = -3;

	cfe_env = "SATA_TX_PRE";
	tmp_envbuf[0] = 0;
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,    strlen(cfe_env),
				   (void *)tmp_envbuf, sizeof(tmp_envbuf));
	if (res == 0 && tmp_envbuf[0])
		SATA_TX_PRE = bcm_atoi(tmp_envbuf);
	else if (res)
		res = -3;

	cfe_env = "USB_IPP";
	tmp_envbuf[0] = 0;
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,    strlen(cfe_env),
				   (void *)tmp_envbuf, sizeof(tmp_envbuf));
	if (res == 0 && tmp_envbuf[0])
		USB_IPP = bcm_atoi(tmp_envbuf);
	else if (res)
		res = -3;
#endif

#if defined (CONFIG_SYS_HAS_ADV_CFE)

	/*
	** Get CFE HW INFO
	*/
	cfeparam.xiocb_fcode  = CFE_CMD_GET_BOARD_INFO;
	cfeparam.xiocb_status = 0;
	cfeparam.xiocb_handle = 0;
	cfeparam.xiocb_flags  = 0;
	cfeparam.xiocb_psize  = sizeof(xiocb_boardinfo_t);

	if (cfe_seal == CFE_SEAL) {
		cfe_hwinfo_called = 1;
		cfe_hwinfo_stat = cfe_call(&cfeparam);

		/* Copy the returned xiocb structure to a global for later access */
		cfe_boardinfo = cfeparam;
	}

#endif

	/*
	 * Get the board name string.
	 */
	cfe_env = "CFE_BOARDNAME";
	res = get_cfe_env_variable(&cfeparam,
				   (void *)cfe_env,       strlen(cfe_env),
				   (void *)cfe_boardname, CFE_BOARDNAME_MAX_LEN);
	if (res)
		res = -4;

	return res;
}