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

📄 ar5210.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 4 页
字号:
		goto no;	} no:	return (HAL_EINVAL); yes:	return HAL_OK;	}HAL_BOOLar5k_ar5210_set_capability(struct ath_hal *hal, HAL_CAPABILITY_TYPE cap_type,			   u_int32_t capability, u_int32_t setting, HAL_STATUS *status) {	AR5K_TRACE;	if (status) {		*status = HAL_OK;	}	return (AH_FALSE);}/* * Key table (WEP) functions */HAL_BOOLar5k_ar5210_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher){	/*	 * The AR5210 only supports WEP	 */	if (cipher == HAL_CIPHER_WEP)		return (AH_TRUE);	return (AH_FALSE);}u_int32_tar5k_ar5210_get_keycache_size(struct ath_hal *hal){	return (AR5K_AR5210_KEYCACHE_SIZE);}HAL_BOOLar5k_ar5210_reset_key(struct ath_hal *hal, u_int16_t entry){	int i;	AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);	for (i = 0; i < AR5K_AR5210_KEYCACHE_SIZE; i++)		AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), 0);	return (AH_FALSE);}HAL_BOOLar5k_ar5210_is_key_valid(struct ath_hal *hal, u_int16_t entry){	AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);	/*	 * Check the validation flag at the end of the entry	 */	if (AR5K_REG_READ(AR5K_AR5210_KEYTABLE_MAC1(entry)) &	    AR5K_AR5210_KEYTABLE_VALID)		return (AH_TRUE);	return (AH_FALSE);}HAL_BOOLar5k_ar5210_set_key(struct ath_hal *hal, u_int16_t entry,    const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused){	int i;	u_int32_t key_v[AR5K_AR5210_KEYCACHE_SIZE - 2];	AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);	bzero(&key_v, sizeof(key_v));	switch (keyval->wk_len) {	case AR5K_KEYVAL_LENGTH_40:		bcopy(keyval->wk_key, &key_v[0], 4);		bcopy(keyval->wk_key + 4, &key_v[1], 1);		key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_40;		break;	case AR5K_KEYVAL_LENGTH_104:		bcopy(keyval->wk_key, &key_v[0], 4);		bcopy(keyval->wk_key + 4, &key_v[1], 2);		bcopy(keyval->wk_key + 6, &key_v[2], 4);		bcopy(keyval->wk_key + 10, &key_v[3], 2);		bcopy(keyval->wk_key + 12, &key_v[4], 1);		key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_104;		break;	case AR5K_KEYVAL_LENGTH_128:		bcopy(keyval->wk_key, &key_v[0], 4);		bcopy(keyval->wk_key + 4, &key_v[1], 2);		bcopy(keyval->wk_key + 6, &key_v[2], 4);		bcopy(keyval->wk_key + 10, &key_v[3], 2);		bcopy(keyval->wk_key + 12, &key_v[4], 4);		key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_128;		break;	default:		/* Unsupported key length (not WEP40/104/128) */		return (AH_FALSE);	}	for (i = 0; i < AR5K_ELEMENTS(key_v); i++)		AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), key_v[i]);	return (ar5k_ar5210_set_key_lladdr(hal, entry, mac));}HAL_BOOLar5k_ar5210_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,    const u_int8_t *mac){	u_int32_t low_id, high_id;	const u_int8_t *mac_v;	/*	 * Invalid entry (key table overflow)	 */	AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);	/* MAC may be NULL if it's a broadcast key */	mac_v = mac == NULL ? etherbroadcastaddr : mac;	bcopy(mac_v, &low_id, 4);	bcopy(mac_v + 4, &high_id, 2);	high_id |= AR5K_AR5210_KEYTABLE_VALID;	AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC0(entry), low_id);	AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC1(entry), high_id);	return (AH_TRUE);}/* * Power management functions */HAL_BOOLar5k_ar5210_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,    HAL_BOOL set_chip, u_int16_t sleep_duration){	u_int32_t staid;	int i;	staid = AR5K_REG_READ(AR5K_AR5210_STA_ID1);	switch (mode) {	case HAL_PM_AUTO:		staid &= ~AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA;		/* fallthrough */	case HAL_PM_NETWORK_SLEEP:		if (set_chip == AH_TRUE) {			AR5K_REG_WRITE(AR5K_AR5210_SCR,			    AR5K_AR5210_SCR_SLE | sleep_duration);		}		staid |= AR5K_AR5210_STA_ID1_PWR_SV;		break;	case HAL_PM_FULL_SLEEP:		if (set_chip == AH_TRUE) {			AR5K_REG_WRITE(AR5K_AR5210_SCR,			    AR5K_AR5210_SCR_SLE_SLP);		}		staid |= AR5K_AR5210_STA_ID1_PWR_SV;		break;	case HAL_PM_AWAKE:		if (set_chip == AH_FALSE)			goto commit;		AR5K_REG_WRITE(AR5K_AR5210_SCR, AR5K_AR5210_SCR_SLE_WAKE);		for (i = 5000; i > 0; i--) {			/* Check if the AR5210 did wake up */			if ((AR5K_REG_READ(AR5K_AR5210_PCICFG) &			    AR5K_AR5210_PCICFG_SPWR_DN) == 0)				break;			/* Wait a bit and retry */			AR5K_DELAY(200);			AR5K_REG_WRITE(AR5K_AR5210_SCR,			    AR5K_AR5210_SCR_SLE_WAKE);		}		/* Fail if the AR5210 didn't wake up */		if (i <= 0)			return (AH_FALSE);		staid &= ~AR5K_AR5210_STA_ID1_PWR_SV;		break;	default:		return (AH_FALSE);	} commit:	hal->ah_power_mode = mode;	AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, staid);	return (AH_TRUE);}HAL_POWER_MODEar5k_ar5210_get_power_mode(struct ath_hal *hal){	return (hal->ah_power_mode);}HAL_BOOLar5k_ar5210_query_pspoll_support(struct ath_hal *hal){	/* I think so, why not? */	return (AH_TRUE);}HAL_BOOLar5k_ar5210_init_pspoll(struct ath_hal *hal){	/*	 * Not used on the AR5210	 */	return (AH_FALSE);}HAL_BOOLar5k_ar5210_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,    u_int16_t assoc_id){	AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,	    AR5K_AR5210_STA_ID1_NO_PSPOLL |	    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);	return (AH_TRUE);}HAL_BOOLar5k_ar5210_disable_pspoll(struct ath_hal *hal){	AR5K_REG_ENABLE_BITS(AR5K_AR5210_STA_ID1,	    AR5K_AR5210_STA_ID1_NO_PSPOLL |	    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);	return (AH_TRUE);}HAL_BOOL /*Unimplemented*/ar5k_ar5210_set_txpower_limit(struct ath_hal *hal, u_int32_t power){	AR5K_TRACE;	return (AH_FALSE);}/* * Beacon functions */voidar5k_ar5210_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,    u_int32_t interval){	u_int32_t timer1, timer2, timer3;	/*	 * Set the additional timers by mode	 */	switch (hal->ah_op_mode) {	case HAL_M_STA:		timer1 = 0xffffffff;		timer2 = 0xffffffff;		timer3 = 1;		break;	default:		timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;		timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;		timer3 = next_beacon + hal->ah_atim_window;		break;	}	/*	 * Enable all timers and set the beacon register	 * (next beacon, DMA beacon, software beacon, ATIM window time)	 */	AR5K_REG_WRITE(AR5K_AR5210_TIMER0, next_beacon);	AR5K_REG_WRITE(AR5K_AR5210_TIMER1, timer1);	AR5K_REG_WRITE(AR5K_AR5210_TIMER2, timer2);	AR5K_REG_WRITE(AR5K_AR5210_TIMER3, timer3);	AR5K_REG_WRITE(AR5K_AR5210_BEACON, interval &	    (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_RESET_TSF |		AR5K_AR5210_BEACON_EN));}void /*Removed arguments - should be changed through *state - review HAL_BEACON_STATE struct*/ar5k_ar5210_set_beacon_timers(struct ath_hal *hal, const HAL_BEACON_STATE *state){	u_int32_t cfp_period, next_cfp;	u_int32_t dtim_count = 0; /* XXX */	u_int32_t cfp_count = 0; /* XXX */	u_int32_t tsf = 0; /* XXX */	/* Return on an invalid beacon state */	if (state->bs_interval < 1)		return;	/*	 * PCF support?	 */	if (state->bs_cfp_period > 0) {		/* Enable CFP mode and set the CFP and timer registers */		cfp_period = state->bs_cfp_period * state->bs_dtim_period *		    state->bs_interval;		next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *		    state->bs_interval;		AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,		    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |		    AR5K_AR5210_STA_ID1_PCF);		AR5K_REG_WRITE(AR5K_AR5210_CFP_PERIOD, cfp_period);		AR5K_REG_WRITE(AR5K_AR5210_CFP_DUR, state->bs_cfp_max_duration);		AR5K_REG_WRITE(AR5K_AR5210_TIMER2,		    (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);	} else {		/* Disable PCF mode */		AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,		    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |		    AR5K_AR5210_STA_ID1_PCF);	}	/*	 * Enable the beacon timer register	 */	AR5K_REG_WRITE(AR5K_AR5210_TIMER0, state->bs_next_beacon);	/*	 * Start the beacon timers	 */	AR5K_REG_WRITE(AR5K_AR5210_BEACON,	    (AR5K_REG_READ(AR5K_AR5210_BEACON) &~		(AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_TIM)) |	    AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,		AR5K_AR5210_BEACON_TIM) |	    AR5K_REG_SM(state->bs_interval, AR5K_AR5210_BEACON_PERIOD));	/*	 * Write new beacon miss threshold, if it appears to be valid	 */	if (state->bs_bmiss_threshold <=	    (AR5K_AR5210_RSSI_THR_BM_THR >> AR5K_AR5210_RSSI_THR_BM_THR_S)) {		AR5K_REG_WRITE_BITS(AR5K_AR5210_RSSI_THR,		    AR5K_AR5210_RSSI_THR_BM_THR, state->bs_bmiss_threshold);	}}voidar5k_ar5210_reset_beacon(struct ath_hal *hal){	/*	 * Disable beacon timer	 */	AR5K_REG_WRITE(AR5K_AR5210_TIMER0, 0);	/*	 * Disable some beacon register values	 */	AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,	    AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5210_STA_ID1_PCF);	AR5K_REG_WRITE(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_PERIOD);}HAL_BOOLar5k_ar5210_wait_for_beacon(struct ath_hal *hal, HAL_BUS_ADDR phys_addr){	int i;	/*	 * Wait for beaconn queue to be done	 */	for (i = (AR5K_TUNE_BEACON_INTERVAL / 2); i > 0 &&		 (AR5K_REG_READ(AR5K_AR5210_BSR) &		     AR5K_AR5210_BSR_TXQ1F) != 0 &&		 (AR5K_REG_READ(AR5K_AR5210_CR) &		     AR5K_AR5210_CR_TXE1) != 0; i--);	/* Timeout... */	if (i <= 0) {		/*		 * Re-schedule the beacon queue		 */		AR5K_REG_WRITE(AR5K_AR5210_TXDP1, (u_int32_t)phys_addr);		AR5K_REG_WRITE(AR5K_AR5210_BCR,		    AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);		return (AH_FALSE);	}	return (AH_TRUE);}/* * Interrupt handling */HAL_BOOLar5k_ar5210_is_intr_pending(struct ath_hal *hal){	return (AR5K_REG_READ(AR5K_AR5210_INTPEND) == 0 ? AH_FALSE : AH_TRUE);}HAL_BOOLar5k_ar5210_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask){	u_int32_t data;	if ((data = AR5K_REG_READ(AR5K_AR5210_ISR)) == HAL_INT_NOCARD) {		*interrupt_mask = data;		return (AH_FALSE);	}	/*	 * Get abstract interrupt mask (HAL-compatible)	 */	*interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;	if (data & (AR5K_AR5210_ISR_RXOK | AR5K_AR5210_ISR_RXERR))		*interrupt_mask |= HAL_INT_RX;	if (data & (AR5K_AR5210_ISR_TXOK | AR5K_AR5210_ISR_TXERR))		*interrupt_mask |= HAL_INT_TX;	if (data & AR5K_AR5210_ISR_FATAL)		*interrupt_mask |= HAL_INT_FATAL;	/*	 * Special interrupt handling (not caught by the driver)	 */	if (((*interrupt_mask) & AR5K_AR5210_ISR_RXPHY) &&	    hal->ah_radar.r_enabled == AH_TRUE)		ar5k_radar_alert(hal);	/* XXX BMISS interrupts may occur after association */	*interrupt_mask &= ~HAL_INT_BMISS;	return (AH_TRUE);}u_int32_tar5k_ar5210_get_intr(struct ath_hal *hal){	/* Return the interrupt mask stored previously */	return (hal->ah_imr);}HAL_INTar5k_ar5210_set_intr(struct ath_hal *hal, HAL_INT new_mask){	HAL_INT old_mask, int_mask;	/*	 * Disable card interrupts to prevent any race conditions	 * (they will be re-enabled afterwards).	 */	AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);	old_mask = hal->ah_imr;	/*	 * Add additional, chipset-dependent interrupt mask flags	 * and write them to the IMR (interrupt mask register).	 */	int_mask = new_mask & HAL_INT_COMMON;	if (new_mask & HAL_INT_RX)		int_mask |=		    AR5K_AR5210_IMR_RXOK |		    AR5K_AR5210_IMR_RXERR |		    AR5K_AR5210_IMR_RXORN;	if (new_mask & HAL_INT_TX)		int_mask |=		    AR5K_AR5210_IMR_TXOK |		    AR5K_AR5210_IMR_TXERR |		    AR5K_AR5210_IMR_TXURN;	AR5K_REG_WRITE(AR5K_AR5210_IMR, int_mask);	/* Store new interrupt mask */	hal->ah_imr = new_mask;	/* ..re-enable interrupts */	if (int_mask) {		AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);	}	return (old_mask);}/* * Misc internal functions */HAL_BOOLar5k_ar5210_get_capabilities(struct ath_hal *hal){	/* Set number of supported TX queues */	hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5210_TX_NUM_QUEUES;	/*	 * Set radio capabilities	 * (The AR5210 only supports the middle 5GHz band)	 */	hal->ah_capabilities.cap_range.range_5ghz_min = 5120;	hal->ah_capabilities.cap_range.range_5ghz_max = 5430;	hal->ah_capabilities.cap_range.range_2ghz_min = 0;	hal->ah_capabilities.cap_range.range_2ghz_max = 0;	/* Set supported modes */	hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;	/* Set number of GPIO pins */	hal->ah_gpio_npins = AR5K_AR5210_NUM_GPIO;	return (AH_TRUE);}voidar5k_ar5210_radar_alert(struct ath_hal *hal, HAL_BOOL enable){	/*	 * Set the RXPHY interrupt to be able to detect	 * possible radar activity.	 */	AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);	if (enable == AH_TRUE) {		AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR,		    AR5K_AR5210_IMR_RXPHY);	} else {		AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR,		    AR5K_AR5210_IMR_RXPHY);	}	AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);}/* * EEPROM access functions */HAL_BOOLar5k_ar5210_eeprom_is_busy(struct ath_hal *hal){	return (AR5K_REG_READ(AR5K_AR5210_CFG) & AR5K_AR5210_CFG_EEBS ?	    AH_TRUE : AH_FALSE);}intar5k_ar5210_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data){	u_int32_t status, timeout;	/* Enable eeprom access */	AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);	/*	 * Prime read pump	 */	(void)AR5K_REG_READ(AR5K_AR5210_EEPROM_BASE + (4 * offset));	for (timeout = 10000; timeout > 0; timeout--) {		AR5K_DELAY(1);		status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);		if (status & AR5K_AR5210_EEPROM_STAT_RDDONE) {			if (status & AR5K_AR5210_EEPROM_STAT_RDERR)				return (EIO);			*data = (u_int16_t)			    (AR5K_REG_READ(AR5K_AR5210_EEPROM_RDATA) & 0xffff);			return (0);		}	}	return (ETIMEDOUT);}intar5k_ar5210_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data){	u_int32_t status, timeout;	/* Enable eeprom access */	AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);	/*	 * Prime write pump	 */	AR5K_REG_WRITE(AR5K_AR5210_EEPROM_BASE + (4 * offset), data);	for (timeout = 10000; timeout > 0; timeout--) {		AR5K_DELAY(1);		status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);		if (status & AR5K_AR5210_EEPROM_STAT_WRDONE) {			if (status & AR5K_AR5210_EEPROM_STAT_WRERR)				return (EIO);			return (0);		}	}	return (ETIMEDOUT);}

⌨️ 快捷键说明

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