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

📄 if_ath.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	ah = _ath_hal_attach(devid, sc, NULL, (void *) dev->mem_start, &status);	if (ah == NULL) {		printk(KERN_ERR "%s: unable to attach hardware: '%s' (HAL status %u)\n",			dev->name, ath_get_hal_status_desc(status), status);		error = ENXIO;		goto bad;	}	if (ah->ah_abi != HAL_ABI_VERSION) {		printk(KERN_ERR "%s: HAL ABI mismatch; "			"driver expects 0x%x, HAL reports 0x%x\n",			dev->name, HAL_ABI_VERSION, ah->ah_abi);		error = ENXIO;		/* XXX */		goto bad;	}	sc->sc_ah = ah;	/*	 * Check if the MAC has multi-rate retry support.	 * We do this by trying to setup a fake extended	 * descriptor.  MAC's that don't have support will	 * return false w/o doing anything.  MAC's that do	 * support it will return true w/o doing anything.	 */	sc->sc_mrretry = ath_hal_setupxtxdesc(ah, NULL, 0,0, 0,0, 0,0);	/*	 * Check if the device has hardware counters for PHY	 * errors.  If so we need to enable the MIB interrupt	 * so we can act on stat triggers.	 */	if (ath_hal_hwphycounters(ah))		sc->sc_needmib = 1;	/*	 * Get the hardware key cache size.	 */	sc->sc_keymax = ath_hal_keycachesize(ah);	if (sc->sc_keymax > ATH_KEYMAX) {		printk("%s: Warning, using only %u entries in %u key cache\n",			dev->name, ATH_KEYMAX, sc->sc_keymax);		sc->sc_keymax = ATH_KEYMAX;	}	/*	 * Reset the key cache since some parts do not	 * reset the contents on initial power up.	 */	for (i = 0; i < sc->sc_keymax; i++)		ath_hal_keyreset(ah, i);	/*	 * Mark key cache slots associated with global keys	 * as in use.  If we knew TKIP was not to be used we	 * could leave the +32, +64, and +32+64 slots free.	 * XXX only for splitmic.	 */	for (i = 0; i < IEEE80211_WEP_NKID; i++) {		setbit(sc->sc_keymap, i);		setbit(sc->sc_keymap, i+32);		setbit(sc->sc_keymap, i+64);		setbit(sc->sc_keymap, i+32+64);	}	/*	 * Collect the channel list using the default country	 * code and including outdoor channels.  The 802.11 layer	 * is resposible for filtering this list based on settings	 * like the phy mode.	 */	if (countrycode != -1)		ath_countrycode = countrycode;	if (outdoor != -1)		ath_outdoor = outdoor;	if (xchanmode != -1)		ath_xchanmode = xchanmode;	error = ath_getchannels(dev, ath_countrycode,			ath_outdoor, ath_xchanmode);	if (error != 0)		goto bad;	ic->ic_country_code = ath_countrycode;	ic->ic_country_outdoor = ath_outdoor;	if (rfkill != -1) {		printk(KERN_INFO "ath_pci: switching rfkill capability %s\n",			rfkill ? "on" : "off");			ath_hal_setrfsilent(ah, rfkill);	}	/*	 * Setup rate tables for all potential media types.	 */	ath_rate_setup(dev, IEEE80211_MODE_11A);	ath_rate_setup(dev, IEEE80211_MODE_11B);	ath_rate_setup(dev, IEEE80211_MODE_11G);	ath_rate_setup(dev, IEEE80211_MODE_TURBO_A);	ath_rate_setup(dev, IEEE80211_MODE_TURBO_G);	/* Setup for half/quarter rates */	ath_setup_subrates(dev);	/* NB: setup here so ath_rate_update is happy */	ath_setcurmode(sc, IEEE80211_MODE_11A);	/*	 * Allocate tx+rx descriptors and populate the lists.	 */	error = ath_desc_alloc(sc);	if (error != 0) {		printk(KERN_ERR "%s: failed to allocate descriptors: %d\n",			dev->name, error);		goto bad;	}	/*	 * Init ic_caps prior to queue init, since WME cap setting	 * depends on queue setup.	 */	ic->ic_caps = 0;	/*	 * Allocate hardware transmit queues: one queue for	 * beacon frames and one data queue for each QoS	 * priority.  Note that the hal handles reseting	 * these queues at the needed time.	 *	 * XXX PS-Poll	 */	sc->sc_bhalq = ath_beaconq_setup(ah);	if (sc->sc_bhalq == (u_int) -1) {		printk(KERN_ERR "%s: unable to setup a beacon xmit queue!\n",			dev->name);		error = EIO;		goto bad2;	}	sc->sc_cabq = ath_txq_setup(sc, HAL_TX_QUEUE_CAB, 0);	if (sc->sc_cabq == NULL) {		printk(KERN_ERR "%s: unable to setup CAB xmit queue!\n",			dev->name);		error = EIO;		goto bad2;	}	/* NB: ensure BK queue is the lowest priority h/w queue */	if (!ath_tx_setup(sc, WME_AC_BK, HAL_WME_AC_BK)) {		printk(KERN_ERR "%s: unable to setup xmit queue for %s traffic!\n",			dev->name, ieee80211_wme_acnames[WME_AC_BK]);		error = EIO;		goto bad2;	}	if (!ath_tx_setup(sc, WME_AC_BE, HAL_WME_AC_BE) ||	    !ath_tx_setup(sc, WME_AC_VI, HAL_WME_AC_VI) ||	    !ath_tx_setup(sc, WME_AC_VO, HAL_WME_AC_VO)) {		/*		 * Not enough hardware tx queues to properly do WME;		 * just punt and assign them all to the same h/w queue.		 * We could do a better job of this if, for example,		 * we allocate queues when we switch from station to		 * AP mode.		 */		if (sc->sc_ac2q[WME_AC_VI] != NULL)			ath_tx_cleanupq(sc, sc->sc_ac2q[WME_AC_VI]);		if (sc->sc_ac2q[WME_AC_BE] != NULL)			ath_tx_cleanupq(sc, sc->sc_ac2q[WME_AC_BE]);		sc->sc_ac2q[WME_AC_BE] = sc->sc_ac2q[WME_AC_BK];		sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK];		sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK];	} else {		/*		 * Mark WME capability since we have sufficient		 * hardware queues to do proper priority scheduling.		 */		ic->ic_caps |= IEEE80211_C_WME;		sc->sc_uapsdq = ath_txq_setup(sc, HAL_TX_QUEUE_UAPSD, 0);		if (sc->sc_uapsdq == NULL)			DPRINTF(sc, ATH_DEBUG_UAPSD, "%s: unable to setup UAPSD xmit queue!\n",				__func__);		else {			ic->ic_caps |= IEEE80211_C_UAPSD;			/*			 * default UAPSD on if HW capable			 */			IEEE80211_COM_UAPSD_ENABLE(ic);		}	}#ifdef ATH_SUPERG_XR	ath_xr_rate_setup(dev);	sc->sc_xrpollint = XR_DEFAULT_POLL_INTERVAL;	sc->sc_xrpollcount = XR_DEFAULT_POLL_COUNT;	strcpy(sc->sc_grppoll_str, XR_DEFAULT_GRPPOLL_RATE_STR);	sc->sc_grpplq.axq_qnum = -1;	sc->sc_xrtxq = ath_txq_setup(sc, HAL_TX_QUEUE_DATA, HAL_XR_DATA);#endif	/*	 * Special case certain configurations.  Note the	 * CAB queue is handled by these specially so don't	 * include them when checking the txq setup mask.	 */	switch (sc->sc_txqsetup &~ ((1<<sc->sc_cabq->axq_qnum) |				(sc->sc_uapsdq ? (1<<sc->sc_uapsdq->axq_qnum) : 0))) {	case 0x01:		ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet_q0, dev);		break;	case 0x0f:		ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet_q0123, dev);		break;	}	sc->sc_setdefantenna = ath_setdefantenna;	sc->sc_rc = ath_rate_attach(sc);	if (sc->sc_rc == NULL) {		error = EIO;		goto bad2;	}	init_timer(&sc->sc_cal_ch);	sc->sc_cal_ch.function = ath_calibrate;	sc->sc_cal_ch.data = (unsigned long) dev;#ifdef ATH_SUPERG_DYNTURBO	init_timer(&sc->sc_dturbo_switch_mode);	sc->sc_dturbo_switch_mode.function = ath_turbo_switch_mode;	sc->sc_dturbo_switch_mode.data = (unsigned long) dev;#endif	sc->sc_blinking = 0;	sc->sc_ledstate = 1;	sc->sc_ledon = 0;			/* low true */	sc->sc_ledidle = msecs_to_jiffies(2700);	/* 2.7sec */	sc->sc_dfstesttime = ATH_DFS_TEST_RETURN_PERIOD;	init_timer(&sc->sc_ledtimer);	init_timer(&sc->sc_dfswaittimer);	init_timer(&sc->sc_dfstesttimer);	sc->sc_ledtimer.data = (unsigned long) sc;	/*	 * Auto-enable soft led processing for IBM cards and for	 * 5211 minipci cards.  Users can also manually enable/disable	 * support with a sysctl.	 */	sc->sc_softled = (devid == AR5212_DEVID_IBM || devid == AR5211_DEVID);	if (sc->sc_softled) {		ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);		ath_hal_gpioset(ah, sc->sc_ledpin, !sc->sc_ledon);	}	/* NB: ether_setup is done by bus-specific code */	dev->open = ath_init;	dev->stop = ath_stop;	dev->hard_start_xmit = ath_hardstart;	dev->tx_timeout = ath_tx_timeout;	dev->watchdog_timeo = 5 * HZ;			/* XXX */	dev->set_multicast_list = ath_mode_init;	dev->do_ioctl = ath_ioctl;	dev->get_stats = ath_getstats;	dev->set_mac_address = ath_set_mac_address; 	dev->change_mtu = ath_change_mtu;	dev->tx_queue_len = ATH_TXBUF - 1;		/* 1 for mgmt frame */#ifdef USE_HEADERLEN_RESV	dev->hard_header_len += sizeof(struct ieee80211_qosframe) +				sizeof(struct llc) +				IEEE80211_ADDR_LEN +				IEEE80211_WEP_IVLEN +				IEEE80211_WEP_KIDLEN;#ifdef ATH_SUPERG_FF	dev->hard_header_len += ATH_FF_MAX_HDR;#endif#endif	ic->ic_dev = dev;	ic->ic_mgtstart = ath_mgtstart;	ic->ic_init = ath_init;	ic->ic_reset = ath_reset;	ic->ic_newassoc = ath_newassoc;	ic->ic_updateslot = ath_updateslot;	ic->ic_wme.wme_update = ath_wme_update;	ic->ic_uapsd_flush = ath_uapsd_flush;	/* XXX not right but it's not used anywhere important */	ic->ic_phytype = IEEE80211_T_OFDM;	ic->ic_opmode = IEEE80211_M_STA;	sc->sc_opmode = HAL_M_STA;	/* 	 * Set the Atheros Advanced Capabilities from station config before 	 * starting 802.11 state machine.  Currently, set only fast-frames 	 * capability.	 */	ic->ic_ath_cap = 0;	sc->sc_fftxqmin = ATH_FF_TXQMIN;#ifdef ATH_SUPERG_FF	ic->ic_ath_cap |= (ath_hal_fastframesupported(ah) ? IEEE80211_ATHC_FF : 0);#endif	ic->ic_ath_cap |= (ath_hal_burstsupported(ah) ? IEEE80211_ATHC_BURST : 0);#ifdef ATH_SUPERG_COMP	ic->ic_ath_cap |= (ath_hal_compressionsupported(ah) ? IEEE80211_ATHC_COMP : 0); #endif#ifdef ATH_SUPERG_DYNTURBO	ic->ic_ath_cap |= (ath_hal_turboagsupported(ah) ? (IEEE80211_ATHC_TURBOP |							IEEE80211_ATHC_AR) : 0);#endif#ifdef ATH_SUPERG_XR	ic->ic_ath_cap |= (ath_hal_xrsupported(ah) ? IEEE80211_ATHC_XR : 0);#endif	ic->ic_caps |=		  IEEE80211_C_IBSS		/* ibss, nee adhoc, mode */		| IEEE80211_C_HOSTAP		/* hostap mode */		| IEEE80211_C_MONITOR		/* monitor mode */		| IEEE80211_C_AHDEMO		/* adhoc demo mode */		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */		| IEEE80211_C_SHSLOT		/* short slot time supported */		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */		| IEEE80211_C_BGSCAN		/* capable of bg scanning */		;	/*	 * Query the hal to figure out h/w crypto support.	 */	if (ath_hal_ciphersupported(ah, HAL_CIPHER_WEP))		ic->ic_caps |= IEEE80211_C_WEP;	if (ath_hal_ciphersupported(ah, HAL_CIPHER_AES_OCB))		ic->ic_caps |= IEEE80211_C_AES;	if (ath_hal_ciphersupported(ah, HAL_CIPHER_AES_CCM))		ic->ic_caps |= IEEE80211_C_AES_CCM;	if (ath_hal_ciphersupported(ah, HAL_CIPHER_CKIP))		ic->ic_caps |= IEEE80211_C_CKIP;	if (ath_hal_ciphersupported(ah, HAL_CIPHER_TKIP)) {		ic->ic_caps |= IEEE80211_C_TKIP;		/*		 * Check if h/w does the MIC and/or whether the		 * separate key cache entries are required to		 * handle both tx+rx MIC keys.		 */		if (ath_hal_ciphersupported(ah, HAL_CIPHER_MIC)) {			ic->ic_caps |= IEEE80211_C_TKIPMIC;			/*			 * Check if h/w does MIC correctly when			 * WMM is turned on.			 */			if (ath_hal_wmetkipmic(ah))				ic->ic_caps |= IEEE80211_C_WME_TKIPMIC;		} 		if (ath_hal_tkipsplit(ah))			sc->sc_splitmic = 1;	}	sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR);#if 0	sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah);#endif	/*	 * TPC support can be done either with a global cap or	 * per-packet support.  The latter is not available on	 * all parts.  We're a bit pedantic here as all parts	 * support a global cap.	 */	sc->sc_hastpc = ath_hal_hastpc(ah);	if (sc->sc_hastpc || ath_hal_hastxpowlimit(ah))		ic->ic_caps |= IEEE80211_C_TXPMGT;	/*	 * Default 11.h to start enabled.	 */	ic->ic_flags |= IEEE80211_F_DOTH;		/*	 * Check for misc other capabilities.	 */	if (ath_hal_hasbursting(ah))		ic->ic_caps |= IEEE80211_C_BURST;	sc->sc_hasbmask = ath_hal_hasbssidmask(ah);	sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);	/*	 * Indicate we need the 802.11 header padded to a	 * 32-bit boundary for 4-address and QoS frames.	 */	ic->ic_flags |= IEEE80211_F_DATAPAD;	/*	 * Query the hal about antenna support	 * Enable rx fast diversity if hal has support	 */	if (ath_hal_hasdiversity(ah)) {		sc->sc_hasdiversity = 1;		ath_hal_setdiversity(ah, AH_TRUE);		sc->sc_diversity = 1;	} else {		sc->sc_hasdiversity = 0;		sc->sc_diversity = 0;		ath_hal_setdiversity(ah, AH_FALSE);	}	sc->sc_defant = ath_hal_getdefantenna(ah);	/*	 * Not all chips have the VEOL support we want to	 * use with IBSS beacons; check here for it.	 */	sc->sc_hasveol = ath_hal_hasveol(ah);	/* get mac address from hardware */	ath_hal_getmac(ah, ic->ic_myaddr);	if (sc->sc_hasbmask) {		ath_hal_getbssidmask(ah, sc->sc_bssidmask);		ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);		ath_hal_setbssidmask(ah, sc->sc_bssidmask);	}	IEEE80211_ADDR_COPY(dev->dev_addr, ic->ic_myaddr);	/* call MI attach routine. */	ieee80211_ifattach(ic);	/* override default methods */	ic->ic_node_alloc = ath_node_alloc;	sc->sc_node_free = ic->ic_node_free;	ic->ic_node_free = ath_node_free;	ic->ic_node_getrssi = ath_node_getrssi;#ifdef ATH_SUPERG_XR	ic->ic_node_move_data = ath_node_move_data;#endif	sc->sc_node_cleanup = ic->ic_node_cleanup;	ic->ic_node_cleanup = ath_node_cleanup;	sc->sc_recv_mgmt = ic->ic_recv_mgmt;	ic->ic_recv_mgmt = ath_recv_mgmt;	ic->ic_vap_create = ath_vap_create;	ic->ic_vap_delete = ath_vap_delete;

⌨️ 快捷键说明

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