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

📄 ar5xxx.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 4 页
字号:
/*	$OpenBSD: ar5xxx.c,v 1.32 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 Atheros Wireless LAN devices. * (Please have a look at ar5xxx.h for further information) */#include "ah_devid.h"#include "ar5xxx.h"/*  * Per chipset attach functions */extern ar5k_attach_t ar5k_ar5210_attach;extern ar5k_attach_t ar5k_ar5211_attach;extern ar5k_attach_t ar5k_ar5212_attach;static const struct {	u_int16_t	vendor;	u_int16_t	device;	ar5k_attach_t	(*attach);} ar5k_known_products[] = {	/*	 * From pcidevs_data.h	 */	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210,	    ar5k_ar5210_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_AP,	    ar5k_ar5210_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_DEFAULT,	    ar5k_ar5210_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211,	    ar5k_ar5211_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_DEFAULT,	    ar5k_ar5211_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5311,	    ar5k_ar5211_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_FPGA11B,	    ar5k_ar5211_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_LEGACY,	    ar5k_ar5211_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_DEFAULT,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_FPGA,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_IBM,	    ar5k_ar5212_attach },	{ PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRDAG675,	    ar5k_ar5212_attach },	{ PCI_VENDOR_3COM2, PCI_PRODUCT_3COM2_3CRPAG175,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_REV2,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_REV7,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_REV8,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_0014,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_0015,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_0016,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_0017,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_0018,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_0019,	    ar5k_ar5212_attach },	{ PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR2413,	    ar5k_ar5212_attach }};static const HAL_RATE_TABLE ar5k_rt_11a = AR5K_RATES_11A;static const HAL_RATE_TABLE ar5k_rt_11b = AR5K_RATES_11B;static const HAL_RATE_TABLE ar5k_rt_11g = AR5K_RATES_11G;static const HAL_RATE_TABLE ar5k_rt_turbo = AR5K_RATES_TURBO;static const HAL_RATE_TABLE ar5k_rt_xr = AR5K_RATES_XR;int		 ar5k_eeprom_read_ants(struct ath_hal *, u_int32_t *, u_int);int		 ar5k_eeprom_read_modes(struct ath_hal *, u_int32_t *, u_int);u_int16_t	 ar5k_eeprom_bin2freq(struct ath_hal *, u_int16_t, u_int);HAL_BOOL	 ar5k_ar5110_channel(struct ath_hal *, HAL_CHANNEL *);u_int32_t	 ar5k_ar5110_chan2athchan(HAL_CHANNEL *);HAL_BOOL	 ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);HAL_BOOL	 ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);HAL_BOOL	 ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);HAL_BOOL	 ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);HAL_BOOL	 ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);HAL_BOOL	 ar5k_ar5112_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);u_int		 ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,    u_int32_t, u_int32_t, HAL_BOOL);/* * Supported channels */static const structieee80211_regchannel ar5k_5ghz_channels[] = IEEE80211_CHANNELS_5GHZ;static const structieee80211_regchannel ar5k_2ghz_channels[] = IEEE80211_CHANNELS_2GHZ;/* * Initial gain optimization values */static const struct ar5k_gain_opt ar5111_gain_opt = AR5K_AR5111_GAIN_OPT;static const struct ar5k_gain_opt ar5112_gain_opt = AR5K_AR5112_GAIN_OPT;/* * Initial register for the radio chipsets */static const struct ar5k_ini_rf ar5111_rf[] = AR5K_AR5111_INI_RF;static const struct ar5k_ini_rf ar5112_rf[] = AR5K_AR5112_INI_RF;static const struct ar5k_ini_rf ar5112a_rf[] = AR5K_AR5112A_INI_RF;static const struct ar5k_ini_rfgain ar5k_rfg[] = AR5K_INI_RFGAIN;/* * Enable to overwrite the country code (use "00" for debug) */#if 0#define COUNTRYCODE "00"#endif/* * Perform a lookup if the device is supported by the HAL */const char * /*O.K.*/ath_hal_probe(u_int16_t vendor, u_int16_t device){	int i;	/*	 * Perform a linear search on the table of supported devices	 */	for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {		if (vendor == ar5k_known_products[i].vendor &&		    device == ar5k_known_products[i].device)			return ("");	}	return (NULL);}/* * Fills in the HAL structure and initialises the device */struct ath_hal * /*O.K. -added country code + get regdomain-*/ath_hal_attach(u_int16_t device, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status){	struct ath_hal *hal = NULL;	ar5k_attach_t *attach = NULL;	u_int8_t mac[IEEE80211_ADDR_LEN];	int i;	*status = HAL_EINVAL;	/*	 * Call the chipset-dependent attach routine by device id	 */	for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {		if (device == ar5k_known_products[i].device &&		    ar5k_known_products[i].attach != NULL)			attach = ar5k_known_products[i].attach;	}	if (attach == NULL) {		*status = HAL_ENXIO;		AR5K_PRINTF("device not supported: 0x%04x\n", device);		return (NULL);	}	if ((hal = malloc(sizeof(struct ath_hal),		 M_DEVBUF, M_NOWAIT)) == NULL) {		*status = HAL_ENOMEM;		AR5K_PRINT("out of memory\n");		return (NULL);	}	bzero(hal, sizeof(struct ath_hal));	hal->ah_sc = sc;	hal->ah_st = st;	hal->ah_sh = sh;	hal->ah_device = device;	hal->ah_sub_vendor = 0; /* XXX unknown?! */	/*	 * HAL information	 */	/* Regulation Stuff */	hal->ah_country_code = AR5K_TUNE_CTRY;	ar5k_get_regdomain(hal);	hal->ah_abi = HAL_ABI_VERSION;	hal->ah_op_mode = HAL_M_STA;	hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;	hal->ah_turbo = AH_FALSE;	hal->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;	hal->ah_imr = 0;	hal->ah_atim_window = 0;	hal->ah_aifs = AR5K_TUNE_AIFS;	hal->ah_cw_min = AR5K_TUNE_CWMIN;	hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;	hal->ah_software_retry = AH_FALSE;	hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;	if ((attach)(device, hal, st, sh, status) == NULL)		goto failed;#ifdef AR5K_DEBUG	hal->ah_dump_state(hal);#endif	/*	 * Get card capabilities, values, ...	 */	if (ar5k_eeprom_init(hal) != 0) {		*status = HAL_EELOCKED;		AR5K_PRINT("unable to init EEPROM\n");		goto failed;	}	/* Get misc capabilities */	if (hal->ah_get_capabilities(hal) != AH_TRUE) {		*status = HAL_EEREAD;		AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",		    device);		goto failed;	}	/* Get MAC address */	if ((*status = ar5k_eeprom_read_mac(hal, mac)) != 0) {		*status = HAL_EEBADMAC;		AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",		    device);		goto failed;	}	hal->ah_set_lladdr(hal, mac);	/* Get rate tables */	if (hal->ah_capabilities.cap_mode & HAL_MODE_11A)		ar5k_rt_copy(&hal->ah_rt_11a, &ar5k_rt_11a);	if (hal->ah_capabilities.cap_mode & HAL_MODE_11B)		ar5k_rt_copy(&hal->ah_rt_11b, &ar5k_rt_11b);	if (hal->ah_capabilities.cap_mode & HAL_MODE_11G)		ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g);	if (hal->ah_capabilities.cap_mode & HAL_MODE_TURBO)		ar5k_rt_copy(&hal->ah_rt_turbo, &ar5k_rt_turbo);	if (hal->ah_capabilities.cap_mode & HAL_MODE_XR)		ar5k_rt_copy(&hal->ah_rt_xr, &ar5k_rt_xr);	/* Initialize the gain optimization values */	if (hal->ah_radio == AR5K_AR5111) {		hal->ah_gain.g_step_idx = ar5111_gain_opt.go_default;		hal->ah_gain.g_step =		    &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];		hal->ah_gain.g_low = 20;		hal->ah_gain.g_high = 35;		hal->ah_gain.g_active = 1;	} else if (hal->ah_radio == AR5K_AR5112) {		hal->ah_gain.g_step_idx = ar5112_gain_opt.go_default;		hal->ah_gain.g_step =		    &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];		hal->ah_gain.g_low = 20;		hal->ah_gain.g_high = 85;		hal->ah_gain.g_active = 1;	}	*status = HAL_OK;	return (hal); failed:	free(hal, M_DEVBUF);	return (NULL);}u_int16_t /*O.K.*/ath_hal_computetxtime(struct ath_hal *hal, const HAL_RATE_TABLE *rates,    u_int32_t frame_length, u_int16_t rate_index, HAL_BOOL short_preamble){	const HAL_RATE *rate;	u_int32_t value;	AR5K_ASSERT_ENTRY(rate_index, rates->rateCount);	/*	 * Get rate by index	 */	rate = &rates->info[rate_index];	/*	 * Calculate the transmission time by operation (PHY) mode	 */	switch (rate->phy) {	case IEEE80211_T_CCK:		/*		 * CCK / DS mode (802.11b)		 */		value = AR5K_CCK_TX_TIME(rate->rateKbps, frame_length,		    (short_preamble && rate->shortPreamble));		break;	case IEEE80211_T_OFDM:		/*		 * Orthogonal Frequency Division Multiplexing		 */		if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rateKbps) == 0)			return (0);		value = AR5K_OFDM_TX_TIME(rate->rateKbps, frame_length);		break;	case IEEE80211_T_TURBO:		/*		 * Orthogonal Frequency Division Multiplexing		 * Atheros "Turbo Mode" (doubled rates)		 */		if (AR5K_TURBO_NUM_BITS_PER_SYM(rate->rateKbps) == 0)			return (0);		value = AR5K_TURBO_TX_TIME(rate->rateKbps, frame_length);		break;	case IEEE80211_T_XR:		/*		 * Orthogonal Frequency Division Multiplexing		 * Atheros "eXtended Range" (XR)		 */		if (AR5K_XR_NUM_BITS_PER_SYM(rate->rateKbps) == 0)			return (0);		value = AR5K_XR_TX_TIME(rate->rateKbps, frame_length);		break;	default:		return (0);	}	return (value);}/*Following 2 functions come from net80211 M.F.*/u_intath_hal_mhz2ieee(u_int mhz, u_int flags){	return (ieee80211_mhz2ieee(mhz, flags));}u_intath_hal_ieee2mhz(u_int ieee, u_int flags){	return (ieee80211_ieee2mhz(ieee, flags));}HAL_BOOL /*O.K.*/ar5k_check_channel(struct ath_hal *hal, u_int16_t freq, u_int flags){	/* Check if the channel is in our supported range */	if (flags & IEEE80211_CHAN_2GHZ) {		if ((freq >= hal->ah_capabilities.cap_range.range_2ghz_min) &&		    (freq <= hal->ah_capabilities.cap_range.range_2ghz_max))			return (AH_TRUE);	} else if (flags & IEEE80211_CHAN_5GHZ) {		if ((freq >= hal->ah_capabilities.cap_range.range_5ghz_min) &&		    (freq <= hal->ah_capabilities.cap_range.range_5ghz_max))			return (AH_TRUE);	}	return (AH_FALSE);}HAL_BOOL /*Ported, added SUPERCHANNEL & country code + FIX in debug mode*/ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels,    u_int max_channels, u_int *channels_size, HAL_CTRY_CODE country, u_int16_t mode,    HAL_BOOL outdoor, HAL_BOOL extended){	u_int i, c;	u_int32_t domain_current;	u_int domain_5ghz, domain_2ghz;	HAL_CHANNEL *all_channels;	HAL_CTRY_CODE country_current;	if ((all_channels = malloc(sizeof(HAL_CHANNEL) * max_channels,	    M_TEMP, M_NOWAIT)) == NULL)		return (AH_FALSE);	i = c = 0;	domain_current = hal->ah_regdomain;	hal->ah_country_code = country;	country_current = hal->ah_country_code;	/*	 * In debugging mode, enable all channels supported by the chipset	 */	if (domain_current == DMN_DEFAULT || SUPERCHANNEL == 1) {		int min, max, freq;		u_int flags;		min = ath_hal_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MIN,		    IEEE80211_CHAN_2GHZ);		max = ath_hal_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MAX,		    IEEE80211_CHAN_2GHZ);		flags = CHANNEL_B | CHANNEL_TG |		    (hal->ah_version == AR5K_AR5211 ?		    CHANNEL_PUREG : CHANNEL_G); debugchan:		for (i = min; i <= max && c < max_channels; i++) {			freq = ath_hal_ieee2mhz(i, flags);			if (ar5k_check_channel(hal, freq, flags) == AH_FALSE)				continue;			all_channels[c].c_channel = freq;			all_channels[c++].c_channel_flags = flags;		}		/* If is there to protect from infinite loop */		if (flags & IEEE80211_CHAN_2GHZ) {/* ath_hal_mhz2ieee returns 1 for IEEE80211_CHANNELS_5GHZ_MIN for loop starts from 1 and all channels are marked as 5GHz M.F.*///			min = ath_hal_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MIN,//			    IEEE80211_CHAN_5GHZ);/* Continue from where we stoped, skip last 2GHz channel */

⌨️ 快捷键说明

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