⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbutils.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (slowclk == SCC_SS_PCI)			return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64));		else			return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32));	} else if (si->sb.ccrev < 10) {		div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);		if (slowclk == SCC_SS_LPO)			return (max? LPOMAXFREQ : LPOMINFREQ);		else if (slowclk == SCC_SS_XTAL)			return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div));		else if (slowclk == SCC_SS_PCI)			return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div));		else			ASSERT(0);	} else {		/* Chipc rev 10 is InstaClock */		div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;		div = 4 * (div + 1);		return (max ? XTALMAXFREQ : (XTALMINFREQ/div));	}	return (0);}static voidBCMINITFN(sb_clkctl_setdelay)(sb_info_t *si, void *chipcregs){	chipcregs_t * cc;	uint slowmaxfreq, pll_delay, slowclk;	uint pll_on_delay, fref_sel_delay;	pll_delay = PLL_DELAY;	/* If the slow clock is not sourced by the xtal then add the xtal_on_delay	 * since the xtal will also be powered down by dynamic clk control logic.	 */	slowclk = sb_slowclk_src(si);	if (slowclk != SCC_SS_XTAL)		pll_delay += XTAL_ON_DELAY;	/* Starting with 4318 it is ILP that is used for the delays */	slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE);	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;	cc = (chipcregs_t *)chipcregs;	W_REG(&cc->pll_on_delay, pll_on_delay);	W_REG(&cc->fref_sel_delay, fref_sel_delay);}/* initialize power control delay registers */voidBCMINITFN(sb_clkctl_init)(sb_t *sbh){	sb_info_t *si;	uint origidx;	chipcregs_t *cc;	si = SB_INFO(sbh);	origidx = si->curidx;	if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)		return;	if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))		goto done;	/* set all Instaclk chip ILP to 1 MHz */	else if (si->sb.ccrev >= 10)		SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT));	sb_clkctl_setdelay(si, (void *)cc);done:	sb_setcoreidx(sbh, origidx);}/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */uint16sb_clkctl_fast_pwrup_delay(sb_t *sbh){	sb_info_t *si;	uint origidx;	chipcregs_t *cc;	uint slowminfreq;	uint16 fpdelay;	uint intr_val = 0;	si = SB_INFO(sbh);	fpdelay = 0;	origidx = si->curidx;	INTR_OFF(si, intr_val);	if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)		goto done;	if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))		goto done;	slowminfreq = sb_slowclk_freq(si, FALSE);	fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq;done:	sb_setcoreidx(sbh, origidx);	INTR_RESTORE(si, intr_val);	return (fpdelay);}/* turn primary xtal and/or pll off/on */intsb_clkctl_xtal(sb_t *sbh, uint what, bool on){	sb_info_t *si;	uint32 in, out, outen;	si = SB_INFO(sbh);	switch (BUSTYPE(si->sb.bustype)) {		case PCI_BUS:			/* pcie core doesn't have any mapping to control the xtal pu */			if (PCIE(si))				return -1;			in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof(uint32));			out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32));			outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof(uint32));			/*			 * Avoid glitching the clock if GPRS is already using it.			 * We can't actually read the state of the PLLPD so we infer it			 * by the value of XTAL_PU which *is* readable via gpioin.			 */			if (on && (in & PCI_CFG_GPIO_XTAL))				return (0);			if (what & XTAL)				outen |= PCI_CFG_GPIO_XTAL;			if (what & PLL)				outen |= PCI_CFG_GPIO_PLL;			if (on) {				/* turn primary xtal on */				if (what & XTAL) {					out |= PCI_CFG_GPIO_XTAL;					if (what & PLL)						out |= PCI_CFG_GPIO_PLL;					OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,					                     sizeof(uint32), out);					OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN,					                     sizeof(uint32), outen);					OSL_DELAY(XTAL_ON_DELAY);				}				/* turn pll on */				if (what & PLL) {					out &= ~PCI_CFG_GPIO_PLL;					OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,					                     sizeof(uint32), out);					OSL_DELAY(2000);				}			} else {				if (what & XTAL)					out &= ~PCI_CFG_GPIO_XTAL;				if (what & PLL)					out |= PCI_CFG_GPIO_PLL;				OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32), out);				OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof(uint32),				                     outen);			}		default:			return (-1);	}	return (0);}/* set dynamic clk control mode (forceslow, forcefast, dynamic) *//*   returns true if we are forcing fast clock */boolsb_clkctl_clk(sb_t *sbh, uint mode){	sb_info_t *si;	uint origidx;	chipcregs_t *cc;	uint32 scc;	uint intr_val = 0;	si = SB_INFO(sbh);	/* chipcommon cores prior to rev6 don't support dynamic clock control */	if (si->sb.ccrev < 6)		return (FALSE);	/* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */	ASSERT(si->sb.ccrev != 10);	INTR_OFF(si, intr_val);	origidx = si->curidx;	/* "Force HT clock on" all the time, no dynamic clk ctl */	if ((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev <= 1))		goto done;	cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);	ASSERT(cc != NULL);	if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))		goto done;	switch (mode) {	case CLK_FAST:	/* force fast (pll) clock */		if (si->sb.ccrev < 10) {			/* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */			sb_clkctl_xtal(&si->sb, XTAL, ON);			SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP);		} else			OR_REG(&cc->system_clk_ctl, SYCC_HR);		break;	case CLK_DYNAMIC:	/* enable dynamic clock control */		if (si->sb.ccrev < 10) {			scc = R_REG(&cc->slow_clk_ctl);			scc &= ~(SCC_FS | SCC_IP | SCC_XC);			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)				scc |= SCC_XC;			W_REG(&cc->slow_clk_ctl, scc);			/* for dynamic control, we have to release our xtal_pu "force on" */			if (scc & SCC_XC)				sb_clkctl_xtal(&si->sb, XTAL, OFF);		} else {			/* Instaclock */			AND_REG(&cc->system_clk_ctl, ~SYCC_HR);		}		break;	default:		ASSERT(0);	}done:	sb_setcoreidx(sbh, origidx);	INTR_RESTORE(si, intr_val);	return (mode == CLK_FAST);}/* register driver interrupt disabling and restoring callback functions */voidsb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn,                          void *intrsenabled_fn, void *intr_arg){	sb_info_t *si;	si = SB_INFO(sbh);	si->intr_arg = intr_arg;	si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn;	si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn;	si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn;	/* save current core id.  when this function called, the current core	 * must be the core which provides driver functions(il, et, wl, etc.)	 */	si->dev_coreid = si->coreid[si->curidx];}voidsb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice,             uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif){	uint vendor, core, unit;	uint chip, chippkg;	char varname[SB_DEVPATH_BUFSZ + 8];	uint8 class, subclass, progif;	char devpath[SB_DEVPATH_BUFSZ];	vendor = sb_corevendor(sbh);	core = sb_coreid(sbh);	unit = sb_coreunit(sbh);	chip = sb_chip(sbh);	chippkg = sb_chippkg(sbh);	progif = 0;	/* Known vendor translations */	switch (vendor) {	case SB_VEND_BCM:		vendor = VENDOR_BROADCOM;		break;	}	/* Determine class based on known core codes */	switch (core) {	case SB_PCI:	case SB_PCIE:		class = PCI_CLASS_BRIDGE;		subclass = PCI_BRIDGE_PCI;		break;	case SB_CC:		class = PCI_CLASS_MEMORY;		subclass = PCI_MEMORY_FLASH;		break;	case SB_D11:		class = PCI_CLASS_NET;		subclass = PCI_NET_OTHER;		/* Let nvram variable override core ID */		sb_devpath(sbh, devpath, sizeof(devpath));		sprintf(varname, "%sdevid", devpath);		if ((core = getintvar(NULL, varname)))			break;		/*		* no longer support wl%did, but keep the code		* here for backward compatibility.		*/		sprintf(varname, "wl%did", unit);		if ((core = getintvar(NULL, varname)))			break;		/* ignore it */		core = 0xffffffff;		break;	default:		class = subclass = progif = 0xff;		break;	}	*pcivendor = (uint16)vendor;	*pcidevice = (uint16)core;	*pciclass = class;	*pcisubclass = subclass;	*pciprogif = progif;}/* use the mdio interface to write to mdio slaves */static intsb_pcie_mdiowrite(sb_info_t *si,  uint physmedia, uint regaddr, uint val){	uint mdiodata;	uint i = 0;	sbpcieregs_t *pcieregs;	pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx);	ASSERT(pcieregs);	/* enable mdio access to SERDES */	W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);	mdiodata = MDIODATA_START | MDIODATA_WRITE |		(physmedia << MDIODATA_DEVADDR_SHF) |		(regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val;	W_REG((&pcieregs->mdiodata), mdiodata);	PR28829_DELAY();	/* retry till the transaction is complete */	while (i < 10) {		if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) {			/* Disable mdio access to SERDES */			W_REG((&pcieregs->mdiocontrol), 0);			return 0;		}		OSL_DELAY(1000);		i++;	}	SB_ERROR(("sb_pcie_mdiowrite: timed out\n"));	/* Disable mdio access to SERDES */	W_REG((&pcieregs->mdiocontrol), 0);	ASSERT(0);	return 1;}/* indirect way to read pcie config regs */uintsb_pcie_readreg(void *sb, void* arg1, uint offset){	sb_info_t *si;	sb_t   *sbh;	uint retval = 0xFFFFFFFF;	sbpcieregs_t *pcieregs;	uint addrtype;	sbh = (sb_t *)sb;	si = SB_INFO(sbh);	ASSERT(PCIE(si));	pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0);	ASSERT(pcieregs);	addrtype = (uint)((uintptr)arg1);	switch (addrtype) {		case PCIE_CONFIGREGS:			W_REG((&pcieregs->configaddr), offset);			retval = R_REG(&(pcieregs->configdata));			break;		case PCIE_PCIEREGS:			W_REG(&(pcieregs->pcieaddr), offset);			retval = R_REG(&(pcieregs->pciedata));			break;		default:			ASSERT(0);			break;	}	return retval;}/* indirect way to write pcie config/mdio/pciecore regs */uintsb_pcie_writereg(sb_t *sbh, void *arg1,  uint offset, uint val){	sb_info_t *si;	sbpcieregs_t *pcieregs;	uint addrtype;	si = SB_INFO(sbh);	ASSERT(PCIE(si));	pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0);	ASSERT(pcieregs);	addrtype = (uint)((uintptr)arg1);	switch (addrtype) {		case PCIE_CONFIGREGS:			W_REG((&pcieregs->configaddr), offset);			W_REG((&pcieregs->configdata), val);			break;		case PCIE_PCIEREGS:			W_REG((&pcieregs->pcieaddr), offset);			W_REG((&pcieregs->pciedata), val);			break;		default:			ASSERT(0);			break;	}	return 0;}/* Build device path. Support SB, PCI, and JTAG for now. */intsb_devpath(sb_t *sbh, char *path, int size){	ASSERT(path);	ASSERT(size >= SB_DEVPATH_BUFSZ);	switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) {	case PCI_BUS:		ASSERT((SB_INFO(sbh))->osh);		sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh),			OSL_PCI_SLOT((SB_INFO(sbh))->osh));		break;	default:		ASSERT(0);		break;	}	return 0;}/* Fix chip's configuration. The current core may be changed upon return */static intsb_pci_fixcfg(sb_info_t *si){	uint origidx, pciidx;	sbpciregs_t *pciregs;	sbpcieregs_t *pcieregs;	uint16 val16, *reg16;	char name[SB_DEVPATH_BUFSZ+16], *value;	char devpath[SB_DEVPATH_BUFSZ];	ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS);	/* Fix PCI(e) SROM shadow area */	/* save the current index */	origidx = sb_coreidx(&si->sb);	/* check 'pi' is correct and fix it if not */	if (si->sb.buscoretype == SB_PCIE) {		pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0);		ASSERT(pcieregs);		reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];	}	else if (si->sb.buscoretype == SB_PCI) {		pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0);		ASSERT(pciregs);		reg16 = &pciregs->sprom[SRSH_PI_OFFSET];	}	else {		ASSERT(0);		return -1;	}	pciidx = sb_coreidx(&si->sb);	val16 = R_REG(reg16);	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) {		val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK);		W_REG(reg16, val16);	}	/* restore the original index */	sb_setcoreidx(&si->sb, origidx);	/* Fix bar0window */	/* !do it last, it changes the current core! */	if (sb_devpath(&si->sb, devpath, sizeof(devpath)))		return -1;	sprintf(name, "%sb0w", devpath);	if ((value = getvar(NULL, name))) {		OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32),			bcm_strtoul(value, NULL, 16));		/* update curidx since the current core is changed */		si->curidx = _sb_coreidx(si);		if (si->curidx == BADIDX) {			SB_ERROR(("sb_pci_fixcfg: bad core index\n"));			return -1;		}	}	return 0;}static uintsb_chipc_capability(sb_t *sbh){	sb_info_t *si;	si = SB_INFO(sbh);	/* Make sure that there is ChipCommon core present */	if (si->coreid[SB_CC_IDX] == SB_CC)		return (sb_corereg(si, SB_CC_IDX, OFFSETOF(chipcregs_t, capabilities),		                   0, 0));	return 0;}/* Return ADDR64 capability of the backplane */boolsb_backplane64(sb_t *sbh){	return (sb_chipc_capability(sbh) & CAP_BKPLN64);}voidsb_btcgpiowar(sb_t *sbh){	sb_info_t *si;	uint origidx;	uint intr_val = 0;	chipcregs_t *cc;	si = SB_INFO(sbh);	/* Make sure that there is ChipCommon core present &&	 * UART_TX is strapped to 1	 */	if (!(sb_chipc_capability(sbh) & CAP_UARTGPIO))		return;	/* sb_corereg cannot be used as we have to guarantee 8-bit read/writes */	INTR_OFF(si, intr_val);	origidx = sb_coreidx(sbh);	cc = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0);	if (cc == NULL)		goto end;	W_REG(&cc->uart0mcr, R_REG(&cc->uart0mcr) | 0x04);end:	/* restore the original index */	sb_setcoreidx(sbh, origidx);	INTR_RESTORE(si, intr_val);}/* check if the device is removed */boolsb_deviceremoved(sb_t *sbh){	uint32 w;	sb_info_t *si;	si = SB_INFO(sbh);	switch (BUSTYPE(si->sb.bustype)) {	case PCI_BUS:		ASSERT(si->osh);		w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_VID, sizeof(uint32));		if ((w & 0xFFFF) != VENDOR_BROADCOM)			return TRUE;		else			return FALSE;	default:		return FALSE;	}	return FALSE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -