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

📄 ar5211.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 5 页
字号:
	    AR5K_AR5211_KEYTABLE_VALID)		return (AH_TRUE);	return (AH_FALSE);}HAL_BOOLar5k_ar5211_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_AR5211_KEYCACHE_SIZE - 2];	AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_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_AR5211_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_AR5211_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_AR5211_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_AR5211_KEYTABLE_OFF(entry, i), key_v[i]);	return (ar5k_ar5211_set_key_lladdr(hal, entry, mac));}HAL_BOOLar5k_ar5211_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_AR5211_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_AR5211_KEYTABLE_VALID;	AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE_MAC0(entry), low_id);	AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE_MAC1(entry), high_id);	return (AH_TRUE);}/* * Power management functions */HAL_BOOLar5k_ar5211_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_AR5211_STA_ID1);	switch (mode) {	case HAL_PM_AUTO:		staid &= ~AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA;		/* fallthrough */	case HAL_PM_NETWORK_SLEEP:		if (set_chip == AH_TRUE) {			AR5K_REG_WRITE(AR5K_AR5211_SCR,			    AR5K_AR5211_SCR_SLE | sleep_duration);		}		staid |= AR5K_AR5211_STA_ID1_PWR_SV;		break;	case HAL_PM_FULL_SLEEP:		if (set_chip == AH_TRUE) {			AR5K_REG_WRITE(AR5K_AR5211_SCR,			    AR5K_AR5211_SCR_SLE_SLP);		}		staid |= AR5K_AR5211_STA_ID1_PWR_SV;		break;	case HAL_PM_AWAKE:		if (set_chip == AH_FALSE)			goto commit;		AR5K_REG_WRITE(AR5K_AR5211_SCR, AR5K_AR5211_SCR_SLE_WAKE);		for (i = 5000; i > 0; i--) {			/* Check if the AR5211 did wake up */			if ((AR5K_REG_READ(AR5K_AR5211_PCICFG) &			    AR5K_AR5211_PCICFG_SPWR_DN) == 0)				break;			/* Wait a bit and retry */			AR5K_DELAY(200);			AR5K_REG_WRITE(AR5K_AR5211_SCR,			    AR5K_AR5211_SCR_SLE_WAKE);		}		/* Fail if the AR5211 didn't wake up */		if (i <= 0)			return (AH_FALSE);		staid &= ~AR5K_AR5211_STA_ID1_PWR_SV;		break;	default:		return (AH_FALSE);	} commit:	hal->ah_power_mode = mode;	AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, staid);	return (AH_TRUE);}HAL_POWER_MODEar5k_ar5211_get_power_mode(struct ath_hal *hal){	return (hal->ah_power_mode);}HAL_BOOLar5k_ar5211_query_pspoll_support(struct ath_hal *hal){	/* nope */	return (AH_FALSE);}HAL_BOOLar5k_ar5211_init_pspoll(struct ath_hal *hal){	/*	 * Not used on the AR5211	 */	return (AH_FALSE);}HAL_BOOLar5k_ar5211_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,    u_int16_t assoc_id){	return (AH_FALSE);}HAL_BOOLar5k_ar5211_disable_pspoll(struct ath_hal *hal){	return (AH_FALSE);}HAL_BOOL /*Unimplemented*/ar5k_ar5211_set_txpower_limit(struct ath_hal *hal, u_int32_t power){	AR5K_TRACE;	return (AH_FALSE);}/* * Beacon functions */voidar5k_ar5211_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 = 0x0000ffff;		timer2 = 0x0007ffff;		break;	default:		timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<		    0x00000003;		timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<		    0x00000003;	}	timer3 = next_beacon +	    (hal->ah_atim_window ? hal->ah_atim_window : 1);	/*	 * Enable all timers and set the beacon register	 * (next beacon, DMA beacon, software beacon, ATIM window time)	 */	AR5K_REG_WRITE(AR5K_AR5211_TIMER0, next_beacon);	AR5K_REG_WRITE(AR5K_AR5211_TIMER1, timer1);	AR5K_REG_WRITE(AR5K_AR5211_TIMER2, timer2);	AR5K_REG_WRITE(AR5K_AR5211_TIMER3, timer3);	AR5K_REG_WRITE(AR5K_AR5211_BEACON, interval &	    (AR5K_AR5211_BEACON_PERIOD | AR5K_AR5211_BEACON_RESET_TSF |	    AR5K_AR5211_BEACON_ENABLE));}void /*Removed arguments - should be changed through *state - review HAL_BEACON_STATE struct*/ar5k_ar5211_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_AR5211_STA_ID1,		    AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA |		    AR5K_AR5211_STA_ID1_PCF);		AR5K_REG_WRITE(AR5K_AR5211_CFP_PERIOD, cfp_period);		AR5K_REG_WRITE(AR5K_AR5211_CFP_DUR, state->bs_cfp_max_duration);		AR5K_REG_WRITE(AR5K_AR5211_TIMER2,		    (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);	} else {		/* Disable PCF mode */		AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,		    AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA |		    AR5K_AR5211_STA_ID1_PCF);	}	/*	 * Enable the beacon timer register	 */	AR5K_REG_WRITE(AR5K_AR5211_TIMER0, state->bs_next_beacon);	/*	 * Start the beacon timers	 */	AR5K_REG_WRITE(AR5K_AR5211_BEACON,	    (AR5K_REG_READ(AR5K_AR5211_BEACON) &~	    (AR5K_AR5211_BEACON_PERIOD | AR5K_AR5211_BEACON_TIM)) |	    AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,	    AR5K_AR5211_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,	    AR5K_AR5211_BEACON_PERIOD));	/*	 * Write new beacon miss threshold, if it appears to be valid	 */	if ((AR5K_AR5211_RSSI_THR_BMISS >> AR5K_AR5211_RSSI_THR_BMISS_S) <	    state->bs_bmiss_threshold)		return;	AR5K_REG_WRITE_BITS(AR5K_AR5211_RSSI_THR_M,	    AR5K_AR5211_RSSI_THR_BMISS, state->bs_bmiss_threshold);	AR5K_REG_WRITE_BITS(AR5K_AR5211_SCR, AR5K_AR5211_SCR_SLDUR,	    (state->bs_sleepduration - 3) << 3);}voidar5k_ar5211_reset_beacon(struct ath_hal *hal){	/*	 * Disable beacon timer	 */	AR5K_REG_WRITE(AR5K_AR5211_TIMER0, 0);	/*	 * Disable some beacon register values	 */	AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,	    AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5211_STA_ID1_PCF);	AR5K_REG_WRITE(AR5K_AR5211_BEACON, AR5K_AR5211_BEACON_PERIOD);}HAL_BOOLar5k_ar5211_wait_for_beacon(struct ath_hal *hal, HAL_BUS_ADDR phys_addr){	HAL_BOOL ret;	/*	 * Wait for beaconn queue to be done	 */	ret = ar5k_register_timeout(hal,	    AR5K_AR5211_QCU_STS(HAL_TX_QUEUE_ID_BEACON),	    AR5K_AR5211_QCU_STS_FRMPENDCNT, 0, AH_FALSE);	if (AR5K_REG_READ_Q(AR5K_AR5211_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))		return (AH_FALSE);	return (ret);}/* * Interrupt handling */HAL_BOOLar5k_ar5211_is_intr_pending(struct ath_hal *hal){	return (AR5K_REG_READ(AR5K_AR5211_INTPEND) == 0 ? AH_FALSE : AH_TRUE);}HAL_BOOLar5k_ar5211_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask){	u_int32_t data;	/*	 * Read interrupt status from the Read-And-Clear shadow register	 */	data = AR5K_REG_READ(AR5K_AR5211_RAC_PISR);	/*	 * Get abstract interrupt mask (HAL-compatible)	 */	*interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;	if (data == HAL_INT_NOCARD)		return (AH_FALSE);	if (data & (AR5K_AR5211_PISR_RXOK | AR5K_AR5211_PISR_RXERR))		*interrupt_mask |= HAL_INT_RX;	if (data & (AR5K_AR5211_PISR_TXOK | AR5K_AR5211_PISR_TXERR))		*interrupt_mask |= HAL_INT_TX;	if (data & (AR5K_AR5211_PISR_HIUERR))		*interrupt_mask |= HAL_INT_FATAL;	/*	 * Special interrupt handling (not caught by the driver)	 */	if (((*interrupt_mask) & AR5K_AR5211_PISR_RXPHY) &&	    hal->ah_radar.r_enabled == AH_TRUE)		ar5k_radar_alert(hal);	return (AH_TRUE);}u_int32_tar5k_ar5211_get_intr(struct ath_hal *hal){	/* Return the interrupt mask stored previously */	return (hal->ah_imr);}HAL_INTar5k_ar5211_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_AR5211_IER, AR5K_AR5211_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_AR5211_PIMR_RXOK |		    AR5K_AR5211_PIMR_RXERR |		    AR5K_AR5211_PIMR_RXORN |		    AR5K_AR5211_PIMR_RXDESC;	if (new_mask & HAL_INT_TX)		int_mask |=		    AR5K_AR5211_PIMR_TXOK |		    AR5K_AR5211_PIMR_TXERR |		    AR5K_AR5211_PIMR_TXDESC |		    AR5K_AR5211_PIMR_TXURN;	if (new_mask & HAL_INT_FATAL) {		int_mask |= AR5K_AR5211_PIMR_HIUERR;		AR5K_REG_ENABLE_BITS(AR5K_AR5211_SIMR2,		    AR5K_AR5211_SIMR2_MCABT |		    AR5K_AR5211_SIMR2_SSERR |		    AR5K_AR5211_SIMR2_DPERR);	}	AR5K_REG_WRITE(AR5K_AR5211_PIMR, int_mask);	/* Store new interrupt mask */	hal->ah_imr = new_mask;	/* ..re-enable interrupts */	AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_ENABLE);	return (old_mask);}/* * Misc internal functions */HAL_BOOLar5k_ar5211_get_capabilities(struct ath_hal *hal){	u_int16_t ee_header;	/* Capabilities stored in the EEPROM */	ee_header = hal->ah_capabilities.cap_eeprom.ee_header;	/*	 * XXX The AR5211 tranceiver supports frequencies from 4920 to 6100GHz	 * XXX and from 2312 to 2732GHz. There are problems with the current	 * XXX ieee80211 implementation because the IEEE channel mapping	 * XXX does not support negative channel numbers (2312MHz is channel	 * XXX -19). Of course, this doesn't matter because these channels	 * XXX are out of range but some regulation domains like MKK (Japan)	 * XXX will support frequencies somewhere around 4.8GHz.	 */	/*	 * Set radio capabilities	 */	if (AR5K_EEPROM_HDR_11A(ee_header)) {		hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */		hal->ah_capabilities.cap_range.range_5ghz_max = 6100;		/* Set supported modes */		hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;	}	/* This chip will support 802.11b if the 2GHz radio is connected */	if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) {		hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */		hal->ah_capabilities.cap_range.range_2ghz_max = 2732;		hal->ah_capabilities.cap_mode |= HAL_MODE_11B;		if (AR5K_EEPROM_HDR_11B(ee_header))			hal->ah_capabilities.cap_mode |= HAL_MODE_11B;		if (AR5K_EEPROM_HDR_11G(ee_header))			hal->ah_capabilities.cap_mode |= HAL_MODE_11G;	}	/* GPIO */	hal->ah_gpio_npins = AR5K_AR5211_NUM_GPIO;	/* Set number of supported TX queues */	hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5211_TX_NUM_QUEUES;	return (AH_TRUE);}voidar5k_ar5211_radar_alert(struct ath_hal *hal, HAL_BOOL enable){	/*	 * Enable radar detection	 */	AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_DISABLE);	if (enable == AH_TRUE) {		AR5K_REG_WRITE(AR5K_AR5211_PHY_RADAR,		    AR5K_AR5211_PHY_RADAR_ENABLE);		AR5K_REG_ENABLE_BITS(AR5K_AR5211_PIMR,		    AR5K_AR5211_PIMR_RXPHY);	} else {		AR5K_REG_WRITE(AR5K_AR5211

⌨️ 快捷键说明

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