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

📄 ar5212.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 5 页
字号:
/*	$OpenBSD: ar5212.c,v 1.28 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 * (AR5212 + AR5111/AR5112). */#include "ar5xxx.h"#include "ar5212reg.h"#include "ar5212var.h"HAL_BOOL	 ar5k_ar5212_nic_reset(struct ath_hal *, u_int32_t);HAL_BOOL	 ar5k_ar5212_nic_wakeup(struct ath_hal *, u_int16_t);u_int16_t	 ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);void	 ar5k_ar5212_fill(struct ath_hal *);HAL_BOOL	 ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);/* * Initial register setting for the AR5212 */static const struct ar5k_ar5212_ini ar5212_ini[] =    AR5K_AR5212_INI;static const struct ar5k_ar5212_ini_mode ar5212_mode[] =    AR5K_AR5212_INI_MODE;AR5K_HAL_FUNCTIONS(extern, ar5k_ar5212,);void /*Functions added*/ar5k_ar5212_fill(struct ath_hal *hal){	hal->ah_magic = AR5K_AR5212_MAGIC;	/*	 * Init/Exit functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, get_rate_table);	AR5K_HAL_FUNCTION(hal, ar5212, detach);	/*	 * Reset functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, reset);	//AR5K_HAL_FUNCTION(hal, ar5212, set_opmode);	AR5K_HAL_FUNCTION(hal, ar5212, calibrate);	/*	 * TX functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, update_tx_triglevel);	AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queue);	AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queueprops);	AR5K_HAL_FUNCTION(hal, ar5212, release_tx_queue);	AR5K_HAL_FUNCTION(hal, ar5212, reset_tx_queue);	AR5K_HAL_FUNCTION(hal, ar5212, get_tx_buf);	AR5K_HAL_FUNCTION(hal, ar5212, put_tx_buf);	AR5K_HAL_FUNCTION(hal, ar5212, tx_start);	AR5K_HAL_FUNCTION(hal, ar5212, stop_tx_dma);	AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_desc);	AR5K_HAL_FUNCTION(hal, ar5212, setup_xtx_desc);	AR5K_HAL_FUNCTION(hal, ar5212, fill_tx_desc);	AR5K_HAL_FUNCTION(hal, ar5212, proc_tx_desc);	AR5K_HAL_FUNCTION(hal, ar5212, has_veol);	/*	 * RX functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, get_rx_buf);	AR5K_HAL_FUNCTION(hal, ar5212, put_rx_buf);	AR5K_HAL_FUNCTION(hal, ar5212, start_rx);	AR5K_HAL_FUNCTION(hal, ar5212, stop_rx_dma);	AR5K_HAL_FUNCTION(hal, ar5212, start_rx_pcu);	AR5K_HAL_FUNCTION(hal, ar5212, stop_pcu_recv);	AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filter);	AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filterindex);	AR5K_HAL_FUNCTION(hal, ar5212, clear_mcast_filter_idx);	AR5K_HAL_FUNCTION(hal, ar5212, get_rx_filter);	AR5K_HAL_FUNCTION(hal, ar5212, set_rx_filter);	AR5K_HAL_FUNCTION(hal, ar5212, setup_rx_desc);	AR5K_HAL_FUNCTION(hal, ar5212, proc_rx_desc);	AR5K_HAL_FUNCTION(hal, ar5212, set_rx_signal);	/*	 * Misc functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, dump_state);	AR5K_HAL_FUNCTION(hal, ar5212, get_diag_state);	AR5K_HAL_FUNCTION(hal, ar5212, get_lladdr);	AR5K_HAL_FUNCTION(hal, ar5212, set_lladdr);	AR5K_HAL_FUNCTION(hal, ar5212, set_regdomain);	AR5K_HAL_FUNCTION(hal, ar5212, set_ledstate);	AR5K_HAL_FUNCTION(hal, ar5212, set_associd);	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_input);	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_output);	AR5K_HAL_FUNCTION(hal, ar5212, get_gpio);	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio);	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_intr);	AR5K_HAL_FUNCTION(hal, ar5212, get_tsf32);	AR5K_HAL_FUNCTION(hal, ar5212, get_tsf64);	AR5K_HAL_FUNCTION(hal, ar5212, reset_tsf);	AR5K_HAL_FUNCTION(hal, ar5212, get_regdomain);	AR5K_HAL_FUNCTION(hal, ar5212, detect_card_present);	AR5K_HAL_FUNCTION(hal, ar5212, update_mib_counters);	AR5K_HAL_FUNCTION(hal, ar5212, get_rf_gain);	AR5K_HAL_FUNCTION(hal, ar5212, set_slot_time);	AR5K_HAL_FUNCTION(hal, ar5212, get_slot_time);	AR5K_HAL_FUNCTION(hal, ar5212, set_ack_timeout);	AR5K_HAL_FUNCTION(hal, ar5212, get_ack_timeout);	AR5K_HAL_FUNCTION(hal, ar5212, set_cts_timeout);	AR5K_HAL_FUNCTION(hal, ar5212, get_cts_timeout);	/*	 * Key table (WEP) functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, is_cipher_supported);	AR5K_HAL_FUNCTION(hal, ar5212, get_keycache_size);	AR5K_HAL_FUNCTION(hal, ar5212, reset_key);	AR5K_HAL_FUNCTION(hal, ar5212, is_key_valid);	AR5K_HAL_FUNCTION(hal, ar5212, set_key);	AR5K_HAL_FUNCTION(hal, ar5212, set_key_lladdr);	/*	 * Power management functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, set_power);	AR5K_HAL_FUNCTION(hal, ar5212, get_power_mode);	AR5K_HAL_FUNCTION(hal, ar5212, query_pspoll_support);	AR5K_HAL_FUNCTION(hal, ar5212, init_pspoll);	AR5K_HAL_FUNCTION(hal, ar5212, enable_pspoll);	AR5K_HAL_FUNCTION(hal, ar5212, disable_pspoll);	/*	 * Beacon functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, init_beacon);	AR5K_HAL_FUNCTION(hal, ar5212, set_beacon_timers);	AR5K_HAL_FUNCTION(hal, ar5212, reset_beacon);	AR5K_HAL_FUNCTION(hal, ar5212, wait_for_beacon);	/*	 * Interrupt functions	 */	AR5K_HAL_FUNCTION(hal, ar5212, is_intr_pending);	AR5K_HAL_FUNCTION(hal, ar5212, get_isr);	AR5K_HAL_FUNCTION(hal, ar5212, get_intr);	AR5K_HAL_FUNCTION(hal, ar5212, set_intr);	/*	 * Chipset functions (ar5k-specific, non-HAL)	 */	AR5K_HAL_FUNCTION(hal, ar5212, get_capabilities);	AR5K_HAL_FUNCTION(hal, ar5212, radar_alert);	/*	 * EEPROM access	 */	AR5K_HAL_FUNCTION(hal, ar5212, eeprom_is_busy);	AR5K_HAL_FUNCTION(hal, ar5212, eeprom_read);	AR5K_HAL_FUNCTION(hal, ar5212, eeprom_write);	/* Functions not found in OpenBSD */	AR5K_HAL_FUNCTION(hal, ar5212, get_tx_queueprops);	AR5K_HAL_FUNCTION(hal, ar5212, get_capability);	AR5K_HAL_FUNCTION(hal, ar5212, num_tx_pending);	AR5K_HAL_FUNCTION(hal, ar5212, phy_disable);	AR5K_HAL_FUNCTION(hal, ar5212, set_pcu_config);	/*Totaly unimplemented*/	AR5K_HAL_FUNCTION(hal, ar5212, set_capability);	AR5K_HAL_FUNCTION(hal, ar5212, proc_mib_event);	AR5K_HAL_FUNCTION(hal, ar5212, get_tx_inter_queue);	AR5K_HAL_FUNCTION(hal, ar5212, set_txpower_limit);	AR5K_HAL_FUNCTION(hal, ar5212, set_def_antenna);	AR5K_HAL_FUNCTION(hal, ar5212, get_def_antenna);}struct ath_hal * /*Ported & removed an arg from call to set_associd*/ar5k_ar5212_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_TRACE;	ar5k_ar5212_fill(hal);	/* Bring device out of sleep and reset it's units */	if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)		return (NULL);	/* Get MAC, PHY and RADIO revisions */	srev = AR5K_REG_READ(AR5K_AR5212_SREV);	hal->ah_mac_srev = srev;	hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5212_SREV_VER);	hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5212_SREV_REV);	hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5212_PHY_CHIP_ID) &	    0x00ffffffff;	hal->ah_radio_5ghz_revision =	    ar5k_ar5212_radio_revision(hal, HAL_CHIP_5GHZ);	hal->ah_radio_2ghz_revision =	    ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);	/* Single chip radio */	if (hal->ah_radio_2ghz_revision == hal->ah_radio_5ghz_revision)		hal->ah_radio_2ghz_revision = 0;	/* Identify the chipset (this has to be done in an early step) */	hal->ah_version = AR5K_AR5212;	hal->ah_radio = hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112 ?	    AR5K_AR5111 : AR5K_AR5112;	hal->ah_phy = AR5K_AR5212_PHY(0);	bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);	ar5k_ar5212_set_associd(hal, mac, 0);	ar5k_ar5212_get_lladdr(hal, mac);	ar5k_ar5212_set_opmode(hal);	return (hal);}HAL_BOOL /*O.K.*/ar5k_ar5212_nic_reset(struct ath_hal *hal, u_int32_t val){	HAL_BOOL ret = AH_FALSE;	u_int32_t mask = val ? val : ~0;	AR5K_TRACE;	/* Read-and-clear */	AR5K_REG_READ(AR5K_AR5212_RXDP);	/*	 * Reset the device and wait until success	 */	AR5K_REG_WRITE(AR5K_AR5212_RC, val);	/* Wait at least 128 PCI clocks */	AR5K_DELAY(15);	val &=	    AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;	mask &=	    AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;	ret = ar5k_register_timeout(hal, AR5K_AR5212_RC, mask, val, AH_FALSE);	/*	 * Reset configuration register	 */	if ((val & AR5K_AR5212_RC_PCU) == 0)		AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG);	return (ret);}HAL_BOOL /*O.K.*/ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags){	u_int32_t turbo, mode, clock;	turbo = 0;	mode = 0;	clock = 0;	AR5K_TRACE;	/*	 * Get channel mode flags	 */	if (hal->ah_radio >= AR5K_AR5112) {		mode = AR5K_AR5212_PHY_MODE_RAD_AR5112;		clock = AR5K_AR5212_PHY_PLL_AR5112;	} else {		mode = AR5K_AR5212_PHY_MODE_RAD_AR5111;		clock = AR5K_AR5212_PHY_PLL_AR5111;	}	if (flags & IEEE80211_CHAN_2GHZ) {		mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ;		clock |= AR5K_AR5212_PHY_PLL_44MHZ;	} else if (flags & IEEE80211_CHAN_5GHZ) {		mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;		clock |= AR5K_AR5212_PHY_PLL_40MHZ;	} else {		AR5K_PRINT("invalid radio frequency mode\n");		return (AH_FALSE);	}	if (flags & IEEE80211_CHAN_CCK) {		mode |= AR5K_AR5212_PHY_MODE_MOD_CCK;	} else if (flags & IEEE80211_CHAN_OFDM) {		mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM;	} else if (flags & IEEE80211_CHAN_DYN) {		mode |= AR5K_AR5212_PHY_MODE_MOD_DYN;	} else {		AR5K_PRINT("invalid radio frequency mode\n");		return (AH_FALSE);	}	if (flags & IEEE80211_CHAN_TURBO) {		turbo = AR5K_AR5212_PHY_TURBO_MODE |		    AR5K_AR5212_PHY_TURBO_SHORT;	}	/*	 * Reset and wakeup the device	 */	/* ...reset chipset and PCI device */	if (ar5k_ar5212_nic_reset(hal,		AR5K_AR5212_RC_CHIP | AR5K_AR5212_RC_PCI) == AH_FALSE) {		AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");		return (AH_FALSE);	}	/* ...wakeup */	if (ar5k_ar5212_set_power(hal,		HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {		AR5K_PRINT("failed to resume the AR5212 (again)\n");		return (AH_FALSE);	}	/* ...final warm reset */	if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {		AR5K_PRINT("failed to warm reset the AR5212\n");		return (AH_FALSE);	}	/* ...set the PHY operating mode */	AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock);	AR5K_DELAY(300);	AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode);	AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo);	return (AH_TRUE);}u_int16_t /*O.K.*/ar5k_ar5212_radio_revision(struct ath_hal *hal, HAL_CHIP chip){	int i;	u_int32_t srev;	u_int16_t ret;	AR5K_TRACE;	/*	 * Set the radio chip access register	 */	switch (chip) {	case HAL_CHIP_2GHZ:		AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ);		break;	case HAL_CHIP_5GHZ:		AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_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_AR5212_PHY(0x34), 0x00001c16);	for (i = 0; i < 8; i++)		AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000);	srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff;	ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);	/* Reset to the 5GHz mode */	AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);	return (ret);}const HAL_RATE_TABLE * /*O.K.*/ar5k_ar5212_get_rate_table(struct ath_hal *hal, u_int mode){	AR5K_TRACE;	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);	case HAL_MODE_XR:		return (&hal->ah_rt_xr);	default:		return (NULL);	}	return (NULL);}void /*O.K.*/ar5k_ar5212_detach(struct ath_hal *hal){	AR5K_TRACE;	if (hal->ah_rf_banks != NULL)		free(hal->ah_rf_banks, M_DEVBUF);	/*	 * Free HAL structure, assume interrupts are down	 */	free(hal, M_DEVBUF);}HAL_BOOL /*New*/ar5k_ar5212_phy_disable(struct ath_hal *hal){	AR5K_TRACE;	/*Just a try M.F.*/	AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_DISABLE);	return AH_TRUE;}HAL_BOOL /*Ported & removed last argument from call to set_associd*/ar5k_ar5212_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, phy, mode, freq, off, ee_mode, ant[2];	const HAL_RATE_TABLE *rt;	AR5K_TRACE;	*status = HAL_OK;	/*	 * Save some registers before a reset	 */	if (change_channel == AH_TRUE) {		s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));		s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);	} else {		s_seq = 0;		s_ant = 1;	}	s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &	    AR5K_AR5212_PCICFG_LEDSTATE;	s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);	s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);	if (change_channel == AH_TRUE && hal->ah_rf_banks != NULL)		ar5k_ar5212_get_rf_gain(hal);	if (ar5k_ar5212_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE) {		*status = HAL_EIO;		return (AH_FALSE);	}	/*	 * Initialize operating mode	 */	hal->ah_op_mode = op_mode;	if (hal->ah_radio == AR5K_AR5111) {		phy = AR5K_INI_PHY_5111;	} else if (hal->ah_radio == AR5K_AR5112) {		phy = AR5K_INI_PHY_5112;	} else {		AR5K_PRINTF("invalid phy radio: %u\n", hal->ah_radio);

⌨️ 快捷键说明

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