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

📄 ar5211.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 5 页
字号:
/*	$OpenBSD: ar5211.c,v 1.25 2005/12/18 17:59:58 reyk Exp $	*//* * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *//* * HAL interface for the Atheros AR5001 Wireless LAN chipset * (AR5211 + AR5111). */#include "ar5xxx.h"#include "ar5211reg.h"#include "ar5211var.h"HAL_BOOL	 ar5k_ar5211_nic_reset(struct ath_hal *, u_int32_t);HAL_BOOL	 ar5k_ar5211_nic_wakeup(struct ath_hal *, u_int16_t);u_int16_t	 ar5k_ar5211_radio_revision(struct ath_hal *, HAL_CHIP);void	 ar5k_ar5211_fill(struct ath_hal *);void	 ar5k_ar5211_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int,    u_int);/* * Initial register setting for the AR5211 */static const struct ar5k_ini ar5211_ini[] =    AR5K_AR5211_INI;static const struct ar5k_ar5211_ini_mode ar5211_mode[] =    AR5K_AR5211_INI_MODE;static const struct ar5k_ar5211_ini_rf ar5211_rf[] =    AR5K_AR5211_INI_RF;AR5K_HAL_FUNCTIONS(extern, ar5k_ar5211,);voidar5k_ar5211_fill(struct ath_hal *hal){	hal->ah_magic = AR5K_AR5211_MAGIC;	/*	 * Init/Exit functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, get_rate_table);	AR5K_HAL_FUNCTION(hal, ar5211, detach);	/*	 * Reset functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, reset);	AR5K_HAL_FUNCTION(hal, ar5211, set_opmode);	AR5K_HAL_FUNCTION(hal, ar5211, calibrate);	/*	 * TX functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, update_tx_triglevel);	AR5K_HAL_FUNCTION(hal, ar5211, setup_tx_queue);	AR5K_HAL_FUNCTION(hal, ar5211, setup_tx_queueprops);	AR5K_HAL_FUNCTION(hal, ar5211, release_tx_queue);	AR5K_HAL_FUNCTION(hal, ar5211, reset_tx_queue);	AR5K_HAL_FUNCTION(hal, ar5211, get_tx_buf);	AR5K_HAL_FUNCTION(hal, ar5211, put_tx_buf);	AR5K_HAL_FUNCTION(hal, ar5211, tx_start);	AR5K_HAL_FUNCTION(hal, ar5211, stop_tx_dma);	AR5K_HAL_FUNCTION(hal, ar5211, setup_tx_desc);	AR5K_HAL_FUNCTION(hal, ar5211, setup_xtx_desc);	AR5K_HAL_FUNCTION(hal, ar5211, fill_tx_desc);	AR5K_HAL_FUNCTION(hal, ar5211, proc_tx_desc);	AR5K_HAL_FUNCTION(hal, ar5211, has_veol);	/*	 * RX functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, get_rx_buf);	AR5K_HAL_FUNCTION(hal, ar5211, put_rx_buf);	AR5K_HAL_FUNCTION(hal, ar5211, start_rx);	AR5K_HAL_FUNCTION(hal, ar5211, stop_rx_dma);	AR5K_HAL_FUNCTION(hal, ar5211, start_rx_pcu);	AR5K_HAL_FUNCTION(hal, ar5211, stop_pcu_recv);	AR5K_HAL_FUNCTION(hal, ar5211, set_mcast_filter);	AR5K_HAL_FUNCTION(hal, ar5211, set_mcast_filterindex);	AR5K_HAL_FUNCTION(hal, ar5211, clear_mcast_filter_idx);	AR5K_HAL_FUNCTION(hal, ar5211, get_rx_filter);	AR5K_HAL_FUNCTION(hal, ar5211, set_rx_filter);	AR5K_HAL_FUNCTION(hal, ar5211, setup_rx_desc);	AR5K_HAL_FUNCTION(hal, ar5211, proc_rx_desc);	AR5K_HAL_FUNCTION(hal, ar5211, set_rx_signal);	/*	 * Misc functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, dump_state);	AR5K_HAL_FUNCTION(hal, ar5211, get_diag_state);	AR5K_HAL_FUNCTION(hal, ar5211, get_lladdr);	AR5K_HAL_FUNCTION(hal, ar5211, set_lladdr);	AR5K_HAL_FUNCTION(hal, ar5211, set_regdomain);	AR5K_HAL_FUNCTION(hal, ar5211, set_ledstate);	AR5K_HAL_FUNCTION(hal, ar5211, set_associd);	AR5K_HAL_FUNCTION(hal, ar5211, set_gpio_input);	AR5K_HAL_FUNCTION(hal, ar5211, set_gpio_output);	AR5K_HAL_FUNCTION(hal, ar5211, get_gpio);	AR5K_HAL_FUNCTION(hal, ar5211, set_gpio);	AR5K_HAL_FUNCTION(hal, ar5211, set_gpio_intr);	AR5K_HAL_FUNCTION(hal, ar5211, get_tsf32);	AR5K_HAL_FUNCTION(hal, ar5211, get_tsf64);	AR5K_HAL_FUNCTION(hal, ar5211, reset_tsf);	AR5K_HAL_FUNCTION(hal, ar5211, get_regdomain);	AR5K_HAL_FUNCTION(hal, ar5211, detect_card_present);	AR5K_HAL_FUNCTION(hal, ar5211, update_mib_counters);	AR5K_HAL_FUNCTION(hal, ar5211, get_rf_gain);	AR5K_HAL_FUNCTION(hal, ar5211, set_slot_time);	AR5K_HAL_FUNCTION(hal, ar5211, get_slot_time);	AR5K_HAL_FUNCTION(hal, ar5211, set_ack_timeout);	AR5K_HAL_FUNCTION(hal, ar5211, get_ack_timeout);	AR5K_HAL_FUNCTION(hal, ar5211, set_cts_timeout);	AR5K_HAL_FUNCTION(hal, ar5211, get_cts_timeout);	/*	 * Key table (WEP) functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, is_cipher_supported);	AR5K_HAL_FUNCTION(hal, ar5211, get_keycache_size);	AR5K_HAL_FUNCTION(hal, ar5211, reset_key);	AR5K_HAL_FUNCTION(hal, ar5211, is_key_valid);	AR5K_HAL_FUNCTION(hal, ar5211, set_key);	AR5K_HAL_FUNCTION(hal, ar5211, set_key_lladdr);	/*	 * Power management functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, set_power);	AR5K_HAL_FUNCTION(hal, ar5211, get_power_mode);	AR5K_HAL_FUNCTION(hal, ar5211, query_pspoll_support);	AR5K_HAL_FUNCTION(hal, ar5211, init_pspoll);	AR5K_HAL_FUNCTION(hal, ar5211, enable_pspoll);	AR5K_HAL_FUNCTION(hal, ar5211, disable_pspoll);	/*	 * Beacon functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, init_beacon);	AR5K_HAL_FUNCTION(hal, ar5211, set_beacon_timers);	AR5K_HAL_FUNCTION(hal, ar5211, reset_beacon);	AR5K_HAL_FUNCTION(hal, ar5211, wait_for_beacon);	/*	 * Interrupt functions	 */	AR5K_HAL_FUNCTION(hal, ar5211, is_intr_pending);	AR5K_HAL_FUNCTION(hal, ar5211, get_isr);	AR5K_HAL_FUNCTION(hal, ar5211, get_intr);	AR5K_HAL_FUNCTION(hal, ar5211, set_intr);	/*	 * Chipset functions (ar5k-specific, non-HAL)	 */	AR5K_HAL_FUNCTION(hal, ar5211, get_capabilities);	AR5K_HAL_FUNCTION(hal, ar5211, radar_alert);	/*	 * EEPROM access	 */	AR5K_HAL_FUNCTION(hal, ar5211, eeprom_is_busy);	AR5K_HAL_FUNCTION(hal, ar5211, eeprom_read);	AR5K_HAL_FUNCTION(hal, ar5211, eeprom_write);	/* Functions not found in OpenBSD */	AR5K_HAL_FUNCTION(hal, ar5211, get_tx_queueprops);	AR5K_HAL_FUNCTION(hal, ar5211, get_capability);	AR5K_HAL_FUNCTION(hal, ar5211, num_tx_pending);	AR5K_HAL_FUNCTION(hal, ar5211, phy_disable);	AR5K_HAL_FUNCTION(hal, ar5211, set_pcu_config);	/*Totaly unimplemented*/	AR5K_HAL_FUNCTION(hal, ar5211, set_capability);	AR5K_HAL_FUNCTION(hal, ar5211, proc_mib_event);	AR5K_HAL_FUNCTION(hal, ar5211, get_tx_inter_queue);	AR5K_HAL_FUNCTION(hal, ar5211, set_txpower_limit);	AR5K_HAL_FUNCTION(hal, ar5211, set_def_antenna);	AR5K_HAL_FUNCTION(hal, ar5211, get_def_antenna);}struct ath_hal * /*Ported & removed an arg from call to set_associd*/ar5k_ar5211_attach(u_int16_t device, HAL_SOFTC sc, HAL_BUS_TAG st,    HAL_BUS_HANDLE sh, HAL_STATUS *status){	struct ath_hal *hal = (struct ath_hal*) sc;	u_int8_t mac[IEEE80211_ADDR_LEN];	u_int32_t srev;	ar5k_ar5211_fill(hal);	/* Bring device out of sleep and reset it's units */	if (ar5k_ar5211_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)		return (NULL);	/* Get MAC, PHY and RADIO revisions */	srev = AR5K_REG_READ(AR5K_AR5211_SREV);	hal->ah_mac_srev = srev;	hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5211_SREV_VER);	hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5211_SREV_REV);	hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5211_PHY_CHIP_ID) &	    0x00ffffffff;	hal->ah_radio_5ghz_revision =	    ar5k_ar5211_radio_revision(hal, HAL_CHIP_5GHZ);	hal->ah_radio_2ghz_revision = 0;	/* Identify the chipset (this has to be done in an early step) */	hal->ah_version = AR5K_AR5211;	hal->ah_radio = AR5K_AR5111;	hal->ah_phy = AR5K_AR5211_PHY(0);	bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);	ar5k_ar5211_set_associd(hal, mac, 0);	ar5k_ar5211_get_lladdr(hal, mac);	ar5k_ar5211_set_opmode(hal);	return (hal);}HAL_BOOLar5k_ar5211_nic_reset(struct ath_hal *hal, u_int32_t val){	HAL_BOOL ret = AH_FALSE;	u_int32_t mask = val ? val : ~0;	/* Read-and-clear */	AR5K_REG_READ(AR5K_AR5211_RXDP);	/*	 * Reset the device and wait until success	 */	AR5K_REG_WRITE(AR5K_AR5211_RC, val);	/* Wait at least 128 PCI clocks */	AR5K_DELAY(15);	val &=	    AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB;	mask &=	    AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB;	ret = ar5k_register_timeout(hal, AR5K_AR5211_RC, mask, val, AH_FALSE);	/*	 * Reset configuration register	 */	if ((val & AR5K_AR5211_RC_PCU) == 0)		AR5K_REG_WRITE(AR5K_AR5211_CFG, AR5K_AR5211_INIT_CFG);	return (ret);}HAL_BOOLar5k_ar5211_nic_wakeup(struct ath_hal *hal, u_int16_t flags){	u_int32_t turbo, mode, clock;	turbo = 0;	mode = 0;	clock = 0;	/*	 * Get channel mode flags	 */	if (flags & IEEE80211_CHAN_2GHZ) {		mode |= AR5K_AR5211_PHY_MODE_FREQ_2GHZ;		clock |= AR5K_AR5211_PHY_PLL_44MHZ;	} else if (flags & IEEE80211_CHAN_5GHZ) {		mode |= AR5K_AR5211_PHY_MODE_FREQ_5GHZ;		clock |= AR5K_AR5211_PHY_PLL_40MHZ;	} else {		AR5K_PRINT("invalid radio frequency mode\n");		return (AH_FALSE);	}	if ((flags & IEEE80211_CHAN_CCK) ||	    (flags & IEEE80211_CHAN_DYN)) {		/* Dynamic OFDM/CCK is not supported by the AR5211 */		mode |= AR5K_AR5211_PHY_MODE_MOD_CCK;	} else if (flags & IEEE80211_CHAN_OFDM) {		mode |= AR5K_AR5211_PHY_MODE_MOD_OFDM;	} else {		AR5K_PRINT("invalid radio frequency mode\n");		return (AH_FALSE);	}	if (flags & IEEE80211_CHAN_TURBO) {		turbo = AR5K_AR5211_PHY_TURBO_MODE |		    AR5K_AR5211_PHY_TURBO_SHORT;	}	/*	 * Reset and wakeup the device	 */	/* ...reset chipset and PCI device */	if (ar5k_ar5211_nic_reset(hal,		AR5K_AR5211_RC_CHIP | AR5K_AR5211_RC_PCI) == AH_FALSE) {		AR5K_PRINT("failed to reset the AR5211 + PCI chipset\n");		return (AH_FALSE);	}	/* ...wakeup */	if (ar5k_ar5211_set_power(hal,		HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {		AR5K_PRINT("failed to resume the AR5211 (again)\n");		return (AH_FALSE);	}	/* ...final warm reset */	if (ar5k_ar5211_nic_reset(hal, 0) == AH_FALSE) {		AR5K_PRINT("failed to warm reset the AR5211\n");		return (AH_FALSE);	}	/* ...set the PHY operating mode */	AR5K_REG_WRITE(AR5K_AR5211_PHY_PLL, clock);	AR5K_DELAY(300);	AR5K_REG_WRITE(AR5K_AR5211_PHY_MODE, mode);	AR5K_REG_WRITE(AR5K_AR5211_PHY_TURBO, turbo);	return (AH_TRUE);}u_int16_tar5k_ar5211_radio_revision(struct ath_hal *hal, HAL_CHIP chip){	int i;	u_int32_t srev;	u_int16_t ret;	/*	 * Set the radio chip access register	 */	switch (chip) {	case HAL_CHIP_2GHZ:		AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_2GHZ);		break;	case HAL_CHIP_5GHZ:		AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);		break;	default:		return (0);	}	AR5K_DELAY(2000);	/* ...wait until PHY is ready and read the selected radio revision */	AR5K_REG_WRITE(AR5K_AR5211_PHY(0x34), 0x00001c16);	for (i = 0; i < 8; i++)		AR5K_REG_WRITE(AR5K_AR5211_PHY(0x20), 0x00010000);	srev = (AR5K_REG_READ(AR5K_AR5211_PHY(0x100)) >> 24) & 0xff;	ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);	/* Reset to the 5GHz mode */	AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);	return (ret);}const HAL_RATE_TABLE *ar5k_ar5211_get_rate_table(struct ath_hal *hal, u_int mode){	switch (mode) {	case HAL_MODE_11A:		return (&hal->ah_rt_11a);	case HAL_MODE_TURBO:		return (&hal->ah_rt_turbo);	case HAL_MODE_11B:		return (&hal->ah_rt_11b);	case HAL_MODE_11G:	case HAL_MODE_PUREG:		return (&hal->ah_rt_11g);	default:		return (NULL);	}	return (NULL);}void /*O.K.*/ar5k_ar5211_detach(struct ath_hal *hal){	/*	 * Free HAL structure, assume interrupts are down	 */	free(hal, M_DEVBUF);}HAL_BOOL /*New*/ar5k_ar5211_phy_disable(struct ath_hal *hal){	AR5K_TRACE;	/*Just a try M.F.*/	AR5K_REG_WRITE(AR5K_AR5211_PHY_ACTIVE, AR5K_AR5211_PHY_DISABLE);	return AH_TRUE;}HAL_BOOL /*Ported*/ar5k_ar5211_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,    HAL_BOOL change_channel, HAL_STATUS *status){	struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;	u_int8_t mac[IEEE80211_ADDR_LEN];	u_int32_t data, s_seq, s_ant, s_led[3];	u_int i, mode, freq, ee_mode, ant[2];	/*	 * Save some registers before a reset	 */	if (change_channel == AH_TRUE) {		s_seq = AR5K_REG_READ(AR5K_AR5211_DCU_SEQNUM(0));		s_ant = AR5K_REG_READ(AR5K_AR5211_DEFAULT_ANTENNA);	} else {		s_seq = 0;		s_ant = 1;	}	s_led[0] = AR5K_REG_READ(AR5K_AR5211_PCICFG) &	    AR5K_AR5211_PCICFG_LEDSTATE;	s_led[1] = AR5K_REG_READ(AR5K_AR5211_GPIOCR);	s_led[2] = AR5K_REG_READ(AR5K_AR5211_GPIODO);	if (ar5k_ar5211_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)		return (AH_FALSE);	/*	 * Initialize operating mode	 */	hal->ah_op_mode = op_mode;	if (channel->c_channel_flags & IEEE80211_CHAN_A) {		mode = AR5K_INI_VAL_11A;		freq = AR5K_INI_RFGAIN_5GHZ;		ee_mode = AR5K_EEPROM_MODE_11A;	} else if (channel->c_channel_flags & IEEE80211_CHAN_T) {		mode = AR5K_INI_VAL_11A_TURBO;		freq = AR5K_INI_RFGAIN_5GHZ;		ee_mode = AR5K_EEPROM_MODE_11A;	} else if (channel->c_channel_flags & IEEE80211_CHAN_B) {		mode = AR5K_INI_VAL_11B;		freq = AR5K_INI_RFGAIN_2GHZ;		ee_mode = AR5K_EEPROM_MODE_11B;	} else if (channel->c_channel_flags & IEEE80211_CHAN_G) {		mode = AR5K_INI_VAL_11G;		freq = AR5K_INI_RFGAIN_2GHZ;		ee_mode = AR5K_EEPROM_MODE_11G;	} else {		AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);		return (AH_FALSE);	}	/* PHY access enable */	AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);	/*	 * Write initial RF registers	 */	ar5k_ar5211_rfregs(hal, channel, freq, ee_mode);	/*	 * Write initial mode settings	 */	for (i = 0; i < AR5K_ELEMENTS(ar5211_mode); i++) {		AR5K_REG_WAIT(i);		AR5K_REG_WRITE((u_int32_t)ar5211_mode[i].mode_register,		    ar5211_mode[i].mode_value[mode]);	}	/*	 * Write initial register settings	 */	for (i = 0; i < AR5K_ELEMENTS(ar5211_ini); i++) {		if (change_channel == AH_TRUE &&		    ar5211_ini[i].ini_register >= AR5K_AR5211_PCU_MIN &&		    ar5211_ini[i].ini_register <= AR5K_AR5211_PCU_MAX)			continue;		AR5K_REG_WAIT(i);		AR5K_REG_WRITE((u_int32_t)ar5211_ini[i].ini_register,		    ar5211_ini[i].ini_value);	}	/*	 * Write initial RF gain settings	 */	if (ar5k_rfgain(hal, AR5K_INI_PHY_5111, freq) == AH_FALSE)		return (AH_FALSE);	AR5K_DELAY(1000);	/*

⌨️ 快捷键说明

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