Example #1
0
void
dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
{
#ifdef BDC
	struct bdc_header *h;
#ifdef APSTA_PINGTEST
	struct	ether_header *eh;
	int i;
#ifdef DHD_DEBUG
	char eabuf1[ETHER_ADDR_STR_LEN];
	char eabuf2[ETHER_ADDR_STR_LEN];
#endif /* DHD_DEBUG */
#endif /* APSTA_PINGTEST */
#endif /* BDC */

	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

#ifdef BDC
	/* Push BDC header used to convey priority for buses that don't */

#ifdef APSTA_PINGTEST
	eh = (struct ether_header *)PKTDATA(dhd->osh, pktbuf);
#endif

	PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN);

	h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf);

	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
	if (PKTSUMNEEDED(pktbuf))
		h->flags |= BDC_FLAG_SUM_NEEDED;


	h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK);
	h->flags2 = 0;
#ifdef APSTA_PINGTEST
	for (i = 0; i < MAX_GUEST; ++i) {
		if (!ETHER_ISNULLADDR(eh->ether_dhost) &&
		    bcmp(eh->ether_dhost, guest_eas[i].octet, ETHER_ADDR_LEN) == 0) {
			DHD_TRACE(("send on if 1; sa %s, da %s\n",
			       bcm_ether_ntoa((struct ether_addr *)(eh->ether_shost), eabuf1),
			       bcm_ether_ntoa((struct ether_addr *)(eh->ether_dhost), eabuf2)));
			/* assume all guest STAs are on interface 1 */
			h->flags2 = 1;
			break;
		}
	}
#endif /* APSTA_PINGTEST */
	h->rssi = 0;
#endif /* BDC */
	BDC_SET_IF_IDX(h, ifidx);
}
Example #2
0
static int
dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
{
	char eabuf[ETHER_ADDR_STR_LEN];

	struct bcmstrbuf b;
	struct bcmstrbuf *strbuf = &b;

	bcm_binit(strbuf, buf, buflen);

	/* Base DHD info */
	bcm_bprintf(strbuf, "%s\n", dhd_version);
	bcm_bprintf(strbuf, "\n");
	bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
	            dhdp->up, dhdp->txoff, dhdp->busstate);
	bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n",
	            dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz);
	bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n",
	            dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf));
	bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt);

	bcm_bprintf(strbuf, "dongle stats:\n");
	bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n",
	            dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes,
	            dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped);
	bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n",
	            dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes,
	            dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped);
	bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast);

	bcm_bprintf(strbuf, "bus stats:\n");
	bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n",
	            dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors);
	bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n",
	            dhdp->tx_ctlpkts, dhdp->tx_ctlerrs);
	bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n",
	            dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors);
	bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n",
	            dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped, dhdp->rx_flushed);
	bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n",
	            dhdp->rx_readahead_cnt, dhdp->tx_realloc, dhdp->fc_packets);
	bcm_bprintf(strbuf, "wd_dpc_sched %ld\n", dhdp->wd_dpc_sched);
	bcm_bprintf(strbuf, "\n");

	/* Add any prot info */
	dhd_prot_dump(dhdp, strbuf);
	bcm_bprintf(strbuf, "\n");

	/* Add any bus info */
	dhd_bus_dump(dhdp, strbuf);

	return (!strbuf->size ? BCME_BUFTOOSHORT : 0);
}
Example #3
0
int
srom_parsecis(uint8 *cis, char **vars, int *count)
{
	char eabuf[32];
	char *vp, *base;
	uint8 tup, tlen, sromrev = 1;
	int i, j;
	uint varsize;
	bool ag_init = FALSE;
	uint16 w;

	ASSERT(vars);
	ASSERT(count);

	base = vp = MALLOC(VARS_MAX);
	ASSERT(vp);

	i = 0;
	do {
		tup = cis[i++];
		tlen = cis[i++];

		switch (tup) {
		case CISTPL_MANFID:
			vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
			vp++;
			vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
			vp++;
			break;

		case CISTPL_FUNCE:
			if (cis[i] == LAN_NID) {
				ASSERT(cis[i + 1] == ETHER_ADDR_LEN);
				bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf);
				vp += sprintf(vp, "il0macaddr=%s", eabuf);
				vp++;
			}
			break;

		case CISTPL_CFTABLE:
			vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
			vp++;
			break;

		case CISTPL_BRCM_HNBU:
			switch (cis[i]) {
			case HNBU_CHIPID:
				vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]);
				vp++;
				vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]);
				vp++;
				if (tlen == 7) {
					vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]);
					vp++;
				}
				break;

			case HNBU_BOARDREV:
				vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
				vp++;
				break;

			case HNBU_AA:
				vp += sprintf(vp, "aa0=%d", cis[i + 1]);
				vp++;
				break;

			case HNBU_AG:
				vp += sprintf(vp, "ag0=%d", cis[i + 1]);
				vp++;
				ag_init = TRUE;
				break;

			case HNBU_CC:
				vp += sprintf(vp, "cc=%d", cis[i + 1]);
				vp++;
				break;

			case HNBU_PAPARMS:
				vp += sprintf(vp, "pa0maxpwr=%d", cis[i + tlen - 1]);
				vp++;
				if (tlen == 9) {
					/* New version */
					for (j = 0; j < 3; j++) {
						vp += sprintf(vp, "pa0b%d=%d", j,
							      (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]);
						vp++;
					}
					vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
					vp++;
				}
				break;

			case HNBU_OEM:
				vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
					cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
					cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]);
				vp++;
				break;
			case HNBU_BOARDFLAGS:
				w = (cis[i + 2] << 8) + cis[i + 1];
				if (w == 0xffff) w = 0;
				vp += sprintf(vp, "boardflags=%d", w);
				vp++;
				break;
			case HNBU_LED:
				if (cis[i + 1] != 0xff) {
					vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]);
					vp++;
				}
				if (cis[i + 2] != 0xff) {
					vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]);
					vp++;
				}
				if (cis[i + 3] != 0xff) {
					vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]);
					vp++;
				}
				if (cis[i + 4] != 0xff) {
					vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]);
					vp++;
				}
				break;
			}
			break;

		}
		i += tlen;
	} while (tup != 0xff);

	/* Set the srom version */
	vp += sprintf(vp, "sromrev=%d", sromrev);
	vp++;

	/* For now just set boardflags2 to zero */
	vp += sprintf(vp, "boardflags2=0");
	vp++;

	/* if there is no antenna gain field, set default */
	if (ag_init == FALSE) {
		vp += sprintf(vp, "ag0=%d", 0xff);
		vp++;
	}

	/* final nullbyte terminator */
	*vp++ = '\0';
	varsize = (uint)vp - (uint)base;

	ASSERT(varsize < VARS_MAX);

	if (varsize == VARS_MAX) {
		*vars = base;
	} else {
		vp = MALLOC(varsize);
		ASSERT(vp);
		bcopy(base, vp, varsize);
		MFREE(base, VARS_MAX);
		*vars = vp;
	}
	*count = varsize;

	return (0);
}
Example #4
0
static int
dhd_rtt_start(dhd_pub_t *dhd) {
	int err = BCME_OK;
	int mpc = 0;
	int nss, mcs, bw;
	uint32 rspec = 0;
	int8 eabuf[ETHER_ADDR_STR_LEN];
	int8 chanbuf[CHANSPEC_STR_LEN];
	bool set_mpc = FALSE;
	wl_proxd_iovar_t proxd_iovar;
	wl_proxd_params_iovar_t proxd_params;
	wl_proxd_params_iovar_t proxd_tune;
	wl_proxd_params_tof_method_t *tof_params = &proxd_params.u.tof_params;
	rtt_status_info_t *rtt_status;
	rtt_target_info_t *rtt_target;
	NULL_CHECK(dhd, "dhd is NULL", err);

	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	/* turn off mpc in case of non-associted */
	if (!dhd_is_associated(dhd, NULL, NULL)) {
		err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), 1);
		if (err < 0) {
				DHD_ERROR(("%s : failed to set proxd_tune\n", __FUNCTION__));
				goto exit;
		}
		set_mpc = TRUE;
	}

	if (rtt_status->cur_idx >= rtt_status->rtt_config.rtt_target_cnt) {
		err = BCME_RANGE;
		goto exit;
	}
	DHD_RTT(("%s enter\n", __FUNCTION__));
	bzero(&proxd_tune, sizeof(proxd_tune));
	bzero(&proxd_params, sizeof(proxd_params));
	mutex_lock(&rtt_status->rtt_mutex);
	/* Get a target information */
	rtt_target = &rtt_status->rtt_config.target_info[rtt_status->cur_idx];
	mutex_unlock(&rtt_status->rtt_mutex);
	/* set role */
	proxd_iovar.method = PROXD_TOF_METHOD;
	proxd_iovar.mode = WL_PROXD_MODE_INITIATOR;

	/* make sure that proxd is stop */
	//dhd_iovar(dhd, 0, "proxd_stop", (char *)NULL, 0, 1);

	err = dhd_iovar(dhd, 0, "proxd", (char *)&proxd_iovar, sizeof(proxd_iovar), 1);
	if (err < 0 && err != BCME_BUSY) {
		DHD_ERROR(("%s : failed to set proxd %d\n", __FUNCTION__, err));
		goto exit;
	}
	/* mac address */
	bcopy(&rtt_target->addr, &tof_params->tgt_mac, ETHER_ADDR_LEN);
	/* frame count */
	if (rtt_target->ftm_cnt > RTT_MAX_FRAME_CNT)
		rtt_target->ftm_cnt = RTT_MAX_FRAME_CNT;

	if (rtt_target->ftm_cnt)
		tof_params->ftm_cnt = htol16(rtt_target->ftm_cnt);
	else
		tof_params->ftm_cnt = htol16(DEFAULT_FTM_CNT);

	if (rtt_target->retry_cnt > RTT_MAX_RETRY_CNT)
		rtt_target->retry_cnt = RTT_MAX_RETRY_CNT;

	/* retry count */
	if (rtt_target->retry_cnt)
		tof_params->retry_cnt = htol16(rtt_target->retry_cnt);
	else
		tof_params->retry_cnt = htol16(DEFAULT_RETRY_CNT);

	/* chanspec */
	tof_params->chanspec = htol16(rtt_target->chanspec);
	/* set parameter */
	DHD_RTT(("Target addr(Idx %d) %s, Channel : %s for RTT (ftm_cnt %d, rety_cnt : %d)\n",
			rtt_status->cur_idx,
			bcm_ether_ntoa((const struct ether_addr *)&rtt_target->addr, eabuf),
			wf_chspec_ntoa(rtt_target->chanspec, chanbuf), rtt_target->ftm_cnt,
			rtt_target->retry_cnt));

	if (rtt_target->type == RTT_ONE_WAY) {
		proxd_tune.u.tof_tune.flags = htol32(WL_PROXD_FLAG_ONEWAY);
		/* report RTT results for initiator */
		proxd_tune.u.tof_tune.flags |= htol32(WL_PROXD_FLAG_INITIATOR_RPTRTT);
		proxd_tune.u.tof_tune.vhtack = 0;
		tof_params->tx_rate = htol16(WL_RATE_6M);
		tof_params->vht_rate = htol16((WL_RATE_6M >> 16));
	} else { /* RTT TWO WAY */
Example #5
0
/*
 * Initialize nonvolatile variable table from sprom.
 * Return 0 on success, nonzero on error.
 */
static int
initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count)
{
	uint16 w, *b;
	uint8 sromrev = 0;
	struct ether_addr ea;
	char eabuf[32];
	uint32 w32;
	int woff, i;
	char *vp, *base;
	osl_t *osh = sb_osh(sbh);
	bool flash = FALSE;
	char name[SB_DEVPATH_BUFSZ+16], *value;
	char devpath[SB_DEVPATH_BUFSZ];
	int err;

	/*
	 * Apply CRC over SROM content regardless SROM is present or not,
	 * and use variable <devpath>sromrev's existance in flash to decide
	 * if we should return an error when CRC fails or read SROM variables
	 * from flash.
	 */
	b = MALLOC(osh, SROM_MAX);
	ASSERT(b);
	if (!b)
		return -2;

	err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,
	                     64, TRUE);
	if (b[SROM4_SIGN] == SROM4_SIGNATURE) {
		/* sromrev >= 4, read more */
		err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,	SROM4_WORDS, TRUE);
		sromrev = b[SROM4_WORDS - 1] & 0xff;
	} else if (err == 0) {
		/* srom is good and is rev < 4 */
		/* top word of sprom contains version and crc8 */
		sromrev = b[63] & 0xff;
		/* bcm4401 sroms misprogrammed */
		if (sromrev == 0x10)
			sromrev = 1;
	}

	if (err) {
#ifdef WLTEST
		BS_ERROR(("SROM Crc Error, so see if we could use a default\n"));
		w32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
		if (w32 & SPROM_OTPIN_USE) {
			BS_ERROR(("srom crc failed with OTP, use default vars....\n"));
			vp = base =  mfgsromvars;
			if (sb_chip(sbh) == BCM4311_CHIP_ID) {
				BS_ERROR(("setting the devid to be 4311\n"));
				vp += sprintf(vp, "devid=0x4311");
				vp++;
			}
			bcopy(defaultsromvars, 	vp, MFGSROM_DEFVARSLEN);
			vp += MFGSROM_DEFVARSLEN;
			goto varsdone;
		} else {
			BS_ERROR(("srom crc failed with SPROM....\n"));
#endif /* WLTEST */
			if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
				return err;
			sprintf(name, "%ssromrev", devpath);
			if (!(value = getvar(NULL, name)))
				return (-1);
			sromrev = (uint8)bcm_strtoul(value, NULL, 0);
			flash = TRUE;
#ifdef WLTEST
		}
#endif /* WLTEST */
	}

	/* srom version check */
	if (sromrev > 4)
		return (-2);

	ASSERT(vars);
	ASSERT(count);

	base = vp = MALLOC(osh, VARS_MAX);
	ASSERT(vp);
	if (!vp)
		return -2;

	/* read variables from flash */
	if (flash) {
		if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
			goto err;
		goto varsdone;
	}

	vp += sprintf(vp, "sromrev=%d", sromrev);
	vp++;

	if (sromrev >= 4) {
		uint path, pathbase;
		const uint pathbases[MAX_PATH] = {SROM4_PATH0, SROM4_PATH1,
		                                  SROM4_PATH2, SROM4_PATH3};

		vp += sprintf(vp, "boardrev=%d", b[SROM4_BREV]);
		vp++;

		vp += sprintf(vp, "boardflags=%d", (b[SROM4_BFL1] << 16) | b[SROM4_BFL0]);
		vp++;

		vp += sprintf(vp, "boardflags2=%d", (b[SROM4_BFL3] << 16) | b[SROM4_BFL2]);
		vp++;

		/* The macaddr */
		ea.octet[0] = (b[SROM4_MACHI] >> 8) & 0xff;
		ea.octet[1] = b[SROM4_MACHI] & 0xff;
		ea.octet[2] = (b[SROM4_MACMID] >> 8) & 0xff;
		ea.octet[3] = b[SROM4_MACMID] & 0xff;
		ea.octet[4] = (b[SROM4_MACLO] >> 8) & 0xff;
		ea.octet[5] = b[SROM4_MACLO] & 0xff;
		bcm_ether_ntoa(&ea, eabuf);
		vp += sprintf(vp, "macaddr=%s", eabuf);
		vp++;

		w = b[SROM4_CCODE];
		if (w == 0)
			vp += sprintf(vp, "ccode=");
		else
			vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
		vp++;
		vp += sprintf(vp, "regrev=%d", b[SROM4_REGREV]);
		vp++;

		w = b[SROM4_LEDBH10];
		if ((w != 0) && (w != 0xffff)) {
			/* ledbh0 */
			vp += sprintf(vp, "ledbh0=%d", (w & 0xff));
			vp++;

			/* ledbh1 */
			vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff);
			vp++;
		}
Example #6
0
static int
srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count)
{
	char eabuf[32];
	char *vp, *base;
	uint8 *cis, tup, tlen, sromrev = 1;
	int i, j;
	uint varsize;
	bool ag_init = FALSE;
	uint32 w32;

	ASSERT(vars);
	ASSERT(count);

	base = vp = MALLOC(osh, VARS_MAX);
	ASSERT(vp);
	if (!vp)
		return -2;

	while (ciscnt--) {
		cis = *pcis++;
		i = 0;
		do {
			tup = cis[i++];
			tlen = cis[i++];
			if ((i + tlen) >= CIS_SIZE)
				break;

			switch (tup) {
			case CISTPL_MANFID:
				vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
				vp++;
				vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
				vp++;
				break;

			case CISTPL_FUNCE:
				switch (cis[i]) {
				case LAN_NID:
					ASSERT(cis[i + 1] == 6);
					bcm_ether_ntoa((struct ether_addr *)&cis[i + 2], eabuf);
					vp += sprintf(vp, "il0macaddr=%s", eabuf);
					vp++;
					break;
				case 1: 	/* SDIO Extended Data */
					vp += sprintf(vp, "sdmaxblk=%d",
					              (cis[i + 13] << 8) | cis[i + 12]);
					vp++;
					break;
				}
				break;

			case CISTPL_CFTABLE:
				vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
				vp++;
				break;

			case CISTPL_BRCM_HNBU:
				switch (cis[i]) {
				case HNBU_SROMREV:
					sromrev = cis[i + 1];
					break;

				case HNBU_CHIPID:
					vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) +
					              cis[i + 1]);
					vp++;
					vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) +
					              cis[i + 3]);
					vp++;
					if (tlen == 7) {
						vp += sprintf(vp, "chiprev=%d",
						              (cis[i + 6] << 8) + cis[i + 5]);
						vp++;
					}
					break;

				case HNBU_BOARDREV:
					vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
					vp++;
					break;

				case HNBU_AA:
					vp += sprintf(vp, "aa2g=%d", cis[i + 1]);
					vp++;
					break;

				case HNBU_AG:
					vp += sprintf(vp, "ag0=%d", cis[i + 1]);
					vp++;
					ag_init = TRUE;
					break;

				case HNBU_CC:
					ASSERT(sromrev == 1);
					vp += sprintf(vp, "cc=%d", cis[i + 1]);
					vp++;
					break;

				case HNBU_PAPARMS:
					if (tlen == 2) {
						ASSERT(sromrev == 1);
						vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]);
						vp++;
					} else if (tlen >= 9) {
						if (tlen == 10) {
							ASSERT(sromrev == 2);
							vp += sprintf(vp, "opo=%d", cis[i + 9]);
							vp++;
						} else
							ASSERT(tlen == 9);

						for (j = 0; j < 3; j++) {
							vp += sprintf(vp, "pa0b%d=%d", j,
							              (cis[i + (j * 2) + 2] << 8) +
							              cis[i + (j * 2) + 1]);
							vp++;
						}
						vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
						vp++;
						vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]);
						vp++;
					} else
						ASSERT(tlen >= 9);
					break;

				case HNBU_OEM:
					ASSERT(sromrev == 1);
					vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
					              cis[i + 1], cis[i + 2],
					              cis[i + 3], cis[i + 4],
					              cis[i + 5], cis[i + 6],
					              cis[i + 7], cis[i + 8]);
					vp++;
					break;

				case HNBU_BOARDFLAGS:
					w32 = (cis[i + 2] << 8) + cis[i + 1];
					if (tlen == 5)
						w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16);
					vp += sprintf(vp, "boardflags=0x%x", w32);
					vp++;
					break;

				case HNBU_LEDS:
					if (cis[i + 1] != 0xff) {
						vp += sprintf(vp, "ledbh0=%d", cis[i + 1]);
						vp++;
					}
					if (cis[i + 2] != 0xff) {
						vp += sprintf(vp, "ledbh1=%d", cis[i + 2]);
						vp++;
					}
					if (cis[i + 3] != 0xff) {
						vp += sprintf(vp, "ledbh2=%d", cis[i + 3]);
						vp++;
					}
					if (cis[i + 4] != 0xff) {
						vp += sprintf(vp, "ledbh3=%d", cis[i + 4]);
						vp++;
					}
					break;

				case HNBU_CCODE:
				{
					char str[3];
					ASSERT(sromrev > 1);
					str[0] = cis[i + 1];
					str[1] = cis[i + 2];
					str[2] = 0;
					vp += sprintf(vp, "ccode=%s", str);
					vp++;
					vp += sprintf(vp, "cctl=0x%x", cis[i + 3]);
					vp++;
					break;
				}

				case HNBU_CCKPO:
					ASSERT(sromrev > 2);
					vp += sprintf(vp, "cckpo=0x%x",
					              (cis[i + 2] << 8) | cis[i + 1]);
					vp++;
					break;

				case HNBU_OFDMPO:
					ASSERT(sromrev > 2);
					vp += sprintf(vp, "ofdmpo=0x%x",
					              (cis[i + 4] << 24) |
					              (cis[i + 3] << 16) |
					              (cis[i + 2] << 8) |
					              cis[i + 1]);
					vp++;
					break;
				}
				break;

			}
			i += tlen;
		} while (tup != 0xff);
	}

	/* Set the srom version */
	vp += sprintf(vp, "sromrev=%d", sromrev);
	vp++;

	/* if there is no antenna gain field, set default */
	if (ag_init == FALSE) {
		ASSERT(sromrev == 1);
		vp += sprintf(vp, "ag0=%d", 0xff);
		vp++;
	}

	/* final nullbyte terminator */
	*vp++ = '\0';
	varsize = (uint)(vp - base);

	ASSERT((vp - base) < VARS_MAX);

	if (varsize == VARS_MAX) {
		*vars = base;
	} else {
		vp = MALLOC(osh, varsize);
		ASSERT(vp);
		if (vp)
			bcopy(base, vp, varsize);
		MFREE(osh, base, VARS_MAX);
		*vars = vp;
		if (!vp) {
			*count = 0;
			return -2;
		}
	}
	*count = varsize;

	return (0);
}