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

📄 wlc_led.c

📁 wi-fi sources for asus wl138g v2 pci card
💻 C
字号:
/* * Customer-defined whiz band LED maintenance for Broadcom 802.11 Networking Driver. * * Copyright 2005-2006, Broadcom Corporation * All Rights Reserved. *                                      * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. * * * $Id$ */#include <wlc_cfg.h>#include <typedefs.h>#include <bcmdefs.h>#include <osl.h>#include <sbutils.h>#include <bcmutils.h>#include <wlioctl.h>#include <proto/802.11.h>#include <sbhndpio.h>#include <sbhnddma.h>#include <hnddma.h>#include <d11.h>#include <wlc_rate.h>#include <wlc_key.h>#include <wlc_channel.h>#include <wlc_pub.h>#include <wlc_bsscfg.h>#include <wlc_pio.h>#include <wlc.h>#include <wlc_phy.h>#include <wl_export.h>#include <wlc_led.h>#define	LED_BLINK_TIME		10	/* 10ms wlc_led_blink_timer() period */#define LED_NUMDEFAULT		3	/* # of default LEDs */struct led {	uint	pin;		/* gpio pin# == led index# */	uint	behavior;	/* led behavior of this pin */	bool	activehi;	/* polarity */	uint	blinkticks;	/* total number of on/off ticks */	uint8	blinkon;	/* # ticks on */	uint8	blinkoff;	/* # ticks off */};struct led_info {	void		*wlc;	wlc_pub_t	*pub;	struct led	led[WL_LED_NUMGPIO];	/* led fanciness */	bool		act;			/* recent tx/rx data frames */	uint		lasttxrx;		/* prev count of tx+rx frames */};/* blink models */static void wlc_led_blinkfast(struct led *led);static void wlc_led_blinkmed(struct led *led);static void wlc_led_blinkslow(struct led *led);static void wlc_led_blinkoff(struct led *led);/* led behavior function prototypes */static void wlc_led(led_info_t *li, uint32 mask, uint32 val, bool activehi);static void wlc_led_null(led_info_t *li, struct led *led);static void wlc_led_on(led_info_t *li, struct led *led);static void wlc_led_off(led_info_t *li, struct led *led);static void wlc_led_activity(led_info_t *li, struct led *led);static void wlc_led_a_radio(led_info_t *li, struct led *led);static void wlc_led_b_radio(led_info_t *li, struct led *led);static void wlc_led_bgmode(led_info_t *li, struct led *led);static void wlc_led_wi1(led_info_t *li, struct led *led);static void wlc_led_wi2(led_info_t *li, struct led *led);static void wlc_led_wi3(led_info_t *li, struct led *led);static void wlc_led_assoc(led_info_t *li, struct led *led);typedef void (*ledfunc_t)(led_info_t *li, struct led *led);/* use dynamic initialization in wlc_led_attach() for some compiler */static ledfunc_t ledfunc[WL_LED_NUMBEHAVIOR];led_info_t *BCMINITFN(wlc_led_attach)(wlc_pub_t *pub, uint d11_unit, void *cwlc){	led_info_t *li;	struct led *led;	int i;	char name[32];	char *var;	uint val;	WL_TRACE(("wl: wlc_led_attach\n"));	/* init static function array */	ledfunc[0] = wlc_led_null;	ledfunc[1] = wlc_led_on;	ledfunc[2] = wlc_led_activity;	ledfunc[3] = wlc_led_on;	ledfunc[4] = wlc_led_a_radio;	ledfunc[5] = wlc_led_b_radio;	ledfunc[6] = wlc_led_bgmode;	ledfunc[7] = wlc_led_wi1;	ledfunc[8] = wlc_led_wi2;	ledfunc[9] = wlc_led_wi3;	ledfunc[10] = wlc_led_assoc;	ledfunc[11] = wlc_led_null;	if ((li = (led_info_t *)MALLOC(pub->osh, sizeof(led_info_t))) == NULL) {		WL_ERROR(("wlc_led_attach: out of memory, malloced %d bytes", MALLOCED(pub->osh)));		return li;	}	bzero((char *)li, sizeof(led_info_t));	li->wlc = cwlc;	li->pub = pub;	/* init led behaviors */	ASSERT(LED_NUMDEFAULT <= WL_LED_NUMGPIO);	led = &li->led[0];	led->pin = 0;	led->behavior = WL_LED_ACTIVITY;	led->activehi = TRUE;	led++;	led->pin = 1;	led->behavior = WL_LED_BRADIO;	led->activehi = TRUE;	led++;	led->pin = 2;	led->behavior = WL_LED_ARADIO;	led->activehi = TRUE;	for (i = LED_NUMDEFAULT; i < WL_LED_NUMGPIO; i ++) {		led ++;		led->pin = i;		led->behavior = WL_LED_OFF;		led->activehi = TRUE;	}	if (li->pub->sbh->boardvendor == VENDOR_HP)		li->led[0].behavior = WL_LED_RADIO;	/* look for led gpio/behavior nvram overrides */	for (i = 0; i < WL_LED_NUMGPIO; i++) {		led = &li->led[i];		sprintf(name, "wl%dgpio%d", d11_unit, i);		if ((var = getvar(pub->vars, name)) == NULL)			continue;		val = bcm_strtoul(var, NULL, 0);		/* silently ignore old card srom garbage */		if ((val & WL_LED_BEH_MASK) >= WL_LED_NUMBEHAVIOR)			continue;		led->pin = i;	/* gpio pin# == led index# */		led->behavior = val & WL_LED_BEH_MASK;		led->activehi = (val & WL_LED_AL_MASK)? FALSE : TRUE;	}	return li;}voidBCMUNINITFN(wlc_led_detach)(led_info_t *li){	WL_TRACE(("wl: %s: li = %p\n", __FUNCTION__, li));	if (li) {		MFREE(li->pub->osh, li, sizeof(led_info_t));	}}voidBCMINITFN(wlc_led_init)(led_info_t *li, uint32 *gpio){	uint32 mask = 0;	int i;	wlc_pub_t *pub = li->pub;	/* build gpio mask */	for (i = 0; i < WL_LED_NUMGPIO; i++)		if ((li->led[i].behavior) && (li->led[i].behavior != WL_LED_INACTIVE))			mask |= (1 << li->led[i].pin);	*gpio = mask;	/* designate gpios driving LEDs . Make sure that we have the control */	sb_gpiocontrol(pub->sbh, mask, 0, GPIO_DRV_PRIORITY);	sb_gpioled(pub->sbh, mask, mask);	sb_gpioouten(pub->sbh, mask, mask, GPIO_DRV_PRIORITY);	/* set all LEDs off */	sb_gpioout(pub->sbh, mask, 0, GPIO_DRV_PRIORITY);}/* this update can be called regardless driver is "up" or "down" */voidwlc_led_event(led_info_t *li){	wlc_info_t *wlc = (wlc_info_t *)li->wlc;	struct led *led;	int i;	/* silently return if called w/o chip clock */	if (!wlc->sbclk)		return;	/* call each pin behavior function */	for (i = 0; i < WL_LED_NUMGPIO; i++)		if ((led = &li->led[i])->behavior)			ledfunc[led->behavior](li, led);}/* called periodically */voidwlc_led_timer(led_info_t *li){	wlc_pub_t *pub = li->pub;	wlc_info_t *wlc = (wlc_info_t *)li->wlc;	uint txrx;	bool blink;	int i;	/* set/clear act */	txrx = WLCNTVAL(pub->_cnt.txframe) + WLCNTVAL(pub->_cnt.rxframe);	li->act = (txrx != li->lasttxrx) ? TRUE : FALSE;	li->lasttxrx = txrx;	wlc_led_event(li);	/* start/stop periodic led_blink_timer */	blink = FALSE;	for (i = 0; i < WL_LED_NUMGPIO; i++)		if (li->led[i].blinkon || li->led[i].blinkoff)			blink = TRUE;	if (blink && !pub->led_blink_run) {		wl_add_timer(wlc->wl, pub->led_blink_timer, LED_BLINK_TIME, 1);		pub->led_blink_run = TRUE;	} else if (!blink && pub->led_blink_run) {		wl_del_timer(wlc->wl, pub->led_blink_timer);		pub->led_blink_run = FALSE;	}}/* called every 10ms while any led->blinkrate is nonzero */voidwlc_led_blink_timer(led_info_t *li){	struct led *led;	/* blink each pin at its respective blinkrate */	for (led = &li->led[0]; led < &li->led[WL_LED_NUMGPIO]; led++) {		if (led->blinkticks) {			if (led->blinkticks > led->blinkon) {				wlc_led_off(li, led);			} else {				wlc_led_on(li, led);			}			if (--led->blinkticks == 0)				led->blinkticks = led->blinkon + led->blinkoff;		}	}}/* 40ms-on/40ms-off */static voidwlc_led_blinkfast(struct led *led){	if ((led->blinkon == 4) && (led->blinkoff == 4))		return;	led->blinkon = 4;	led->blinkoff = 4;	led->blinkticks = led->blinkon + led->blinkoff;}/* 80ms-on/20ms-off */static voidwlc_led_blinkmed(struct led *led){	if ((led->blinkon == 8) && (led->blinkoff == 2))		return;	led->blinkon = 8;	led->blinkoff = 2;	led->blinkticks = led->blinkon + led->blinkoff;}/* 500ms-on/500ms-off */static voidwlc_led_blinkslow(struct led *led){	if ((led->blinkon == 50) && (led->blinkoff == 50))		return;	led->blinkon = 50;	led->blinkoff = 50;	led->blinkticks = led->blinkon + led->blinkoff;}static voidwlc_led_blinkoff(struct led *led){	led->blinkon = led->blinkoff = led->blinkticks = 0;}/* turn gpio bits on or off */static voidwlc_led(led_info_t *li, uint32 mask, uint32 val, bool activehi){	ASSERT((val & ~mask) == 0);	if (!activehi)		val = ((~val) & mask);	sb_gpioout(li->pub->sbh, mask, val, GPIO_DRV_PRIORITY);}static voidwlc_led_null(led_info_t *li, struct led *led){}static voidwlc_led_on(led_info_t *li, struct led *led){	uint mask, val;	mask = 1 << led->pin;	val = mask;	/* Handle both on and Off cases */	if (!li->pub->up)		val = 0;	wlc_led(li, mask, val, led->activehi);}static voidwlc_led_off(led_info_t *li, struct led *led){	wlc_led(li, (1 << led->pin), 0, led->activehi);}static voidwlc_led_activity(led_info_t *li, struct led *led){	if (!li->pub->up) {		/* make sure li->act is clear since wlc_led_timer may be stopped in wlc_down */		li->act = FALSE;	}	if (li->act)		wlc_led_blinkmed(led);	else {		wlc_led_blinkoff(led);		wlc_led_off(li, led);	}}static voidwlc_led_a_radio(led_info_t *li, struct led *led){	wlc_info_t *wlc = (wlc_info_t *)li->wlc;	uint bits;	bool a_radio;	uint i;	a_radio = FALSE;	if ((NBANDS_PUB(li->pub) == 1) || (wlc->bandlocked == TRUE)) {		if (ISAPHY(wlc->band->pi))			a_radio = TRUE;	} else {		for (i = 0; i < NBANDS_PUB(li->pub); i++)			if (ISAPHY(wlc->bandstate[i].pi))				a_radio = TRUE;	}	bits = a_radio? (1 << led->pin) : 0;	/* when down, but not due to MPC only, turn off radio LED */	if (!li->pub->up)		bits = 0;	wlc_led(li, (1 << led->pin), bits, led->activehi);}static voidwlc_led_b_radio(led_info_t *li, struct led *led){	wlc_info_t *wlc = (wlc_info_t *)li->wlc;	wlc_pub_t *pub = li->pub;	uint bits;	bool b_radio;	uint i;	b_radio = FALSE;	if ((NBANDS_PUB(pub) == 1) || (wlc->bandlocked == TRUE)) {		if (ISBPHY(wlc->band->pi) || ISGPHY(wlc->band->pi))			b_radio = TRUE;	} else {		for (i = 0; i < NBANDS_PUB(pub); i++)			if (ISBPHY(wlc->bandstate[i].pi) ||			    ISGPHY(wlc->bandstate[i].pi))				b_radio = TRUE;	}	bits = b_radio? (1 << led->pin) : 0;	/* when down, but not due to MPC only, turn off radio LED */	if (!pub->up)		bits = 0;	wlc_led(li, (1 << led->pin), bits, led->activehi);}static voidwlc_led_bgmode(led_info_t *li, struct led *led){	wlc_info_t *wlc = (wlc_info_t *)li->wlc;	uint bits;	bits = (li->pub->associated && li->pub->BSS && wlc->band->gmode &&		wlc_rateset_isofdm(li->pub->current_bss.rateset.count,		li->pub->current_bss.rateset.rates)) ?		(1 << led->pin) : 0;	wlc_led(li, bits, bits, led->activehi);}static voidwlc_led_wi1(led_info_t *li, struct led *led){	/* blink if activity, otherwise on */	if (li->act)		wlc_led_blinkmed(led);	else {		wlc_led_blinkoff(led);		wlc_led_on(li, led);	}}/* 11g behavior */static voidwlc_led_wi2(led_info_t *li, struct led *led){	if (li->pub->associated)		if (li->act)			wlc_led_blinkfast(led);		else {			wlc_led_blinkoff(led);			wlc_led_on(li, led);		}	else		wlc_led_blinkslow(led);}/* 11b behavior */static voidwlc_led_wi3(led_info_t *li, struct led *led){	wlc_info_t *wlc = (wlc_info_t *)li->wlc;	if (ISAPHY(wlc->band->pi))		return;	if (li->pub->associated && !wlc_rateset_isofdm(li->pub->current_bss.rateset.count,		li->pub->current_bss.rateset.rates))		if (li->act)			wlc_led_blinkfast(led);		else {			wlc_led_blinkoff(led);			wlc_led_on(li, led);		}	else		wlc_led_blinkslow(led);}static voidwlc_led_assoc(led_info_t *li, struct led *led){	if (!li->pub->up) {		ASSERT(li->pub->associated);		li->pub->associated = FALSE;	}	if (li->pub->associated) {		wlc_led_blinkoff(led);		wlc_led_on(li, led);	} else		wlc_led_blinkslow(led);}/* turn activity LED on or off */voidwlc_led_activityset(led_info_t *li, bool led_state){	struct led *led;	uint i;	for (i = 0; i < WL_LED_NUMGPIO; i++) {		led = &li->led[i];		if (led->behavior == WL_LED_ACTIVITY) {			if (led_state == ON)				wlc_led_on(li, led);			else				wlc_led_off(li, led);		}	}}/* turn radio LEDs on or off when switch band */voidwlc_led_radioset(led_info_t *li, bool led_state){	struct led *led;	uint i;	for (i = 0; i < WL_LED_NUMGPIO; i++) {		led = &li->led[i];		if ((led->behavior == WL_LED_ARADIO) ||		    (led->behavior == WL_LED_BRADIO)) {			if (led_state == ON)				wlc_led_on(li, led);			else				wlc_led_off(li, led);		}	}}

⌨️ 快捷键说明

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