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

📄 ieee80211softmac_module.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Contains some basic softmac functions along with module registration code etc. * * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net> *                          Joseph Jezak <josejx@gentoo.org> *                          Larry Finger <Larry.Finger@lwfinger.net> *                          Danny van Dyk <kugelfang@gentoo.org> *                          Michael Buesch <mbuesch@freenet.de> * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA * * The full GNU General Public License is included in this distribution in the * file called COPYING. */#include "ieee80211softmac_priv.h"#include <linux/sort.h>#include <linux/etherdevice.h>struct net_device *alloc_ieee80211softmac(int sizeof_priv){	struct ieee80211softmac_device *softmac;	struct net_device *dev;	dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);	if (!dev)		return NULL;	softmac = ieee80211_priv(dev);	softmac->wq = create_freezeable_workqueue("softmac");	if (!softmac->wq) {		free_ieee80211(dev);		return NULL;	}	softmac->dev = dev;	softmac->ieee = netdev_priv(dev);	spin_lock_init(&softmac->lock);	softmac->ieee->handle_auth = ieee80211softmac_auth_resp;	softmac->ieee->handle_deauth = ieee80211softmac_deauth_resp;	softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;	softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;	softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;	softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;	softmac->scaninfo = NULL;	softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;	/* TODO: initialise all the other callbacks in the ieee struct	 *	 (once they're written)	 */	INIT_LIST_HEAD(&softmac->auth_queue);	INIT_LIST_HEAD(&softmac->network_list);	INIT_LIST_HEAD(&softmac->events);	mutex_init(&softmac->associnfo.mutex);	INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work);	INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout);	softmac->start_scan = ieee80211softmac_start_scan_implementation;	softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;	softmac->stop_scan = ieee80211softmac_stop_scan_implementation;	/* to start with, we can't send anything ... */	netif_carrier_off(dev);	return dev;}EXPORT_SYMBOL_GPL(alloc_ieee80211softmac);/* Clears the pending work queue items, stops all scans, etc. */voidieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm){	unsigned long flags;	struct ieee80211softmac_event *eventptr, *eventtmp;	struct ieee80211softmac_auth_queue_item *authptr, *authtmp;	struct ieee80211softmac_network *netptr, *nettmp;	ieee80211softmac_stop_scan(sm);	ieee80211softmac_wait_for_scan(sm);	spin_lock_irqsave(&sm->lock, flags);	sm->running = 0;	/* Free all pending assoc work items */	cancel_delayed_work(&sm->associnfo.work);	/* Free all pending scan work items */	if(sm->scaninfo != NULL)		cancel_delayed_work(&sm->scaninfo->softmac_scan);	/* Free all pending auth work items */	list_for_each_entry(authptr, &sm->auth_queue, list)		cancel_delayed_work(&authptr->work);	/* delete all pending event calls and work items */	list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list)		cancel_delayed_work(&eventptr->work);	spin_unlock_irqrestore(&sm->lock, flags);	flush_workqueue(sm->wq);	/* now we should be save and no longer need locking... */	spin_lock_irqsave(&sm->lock, flags);	/* Free all pending auth work items */	list_for_each_entry_safe(authptr, authtmp, &sm->auth_queue, list) {		list_del(&authptr->list);		kfree(authptr);	}	/* delete all pending event calls and work items */	list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list) {		list_del(&eventptr->list);		kfree(eventptr);	}	/* Free all networks */	list_for_each_entry_safe(netptr, nettmp, &sm->network_list, list) {		ieee80211softmac_del_network_locked(sm, netptr);		if(netptr->challenge != NULL)			kfree(netptr->challenge);		kfree(netptr);	}	spin_unlock_irqrestore(&sm->lock, flags);}EXPORT_SYMBOL_GPL(ieee80211softmac_clear_pending_work);void free_ieee80211softmac(struct net_device *dev){	struct ieee80211softmac_device *sm = ieee80211_priv(dev);	ieee80211softmac_clear_pending_work(sm);	kfree(sm->scaninfo);	kfree(sm->wpa.IE);	destroy_workqueue(sm->wq);	free_ieee80211(dev);}EXPORT_SYMBOL_GPL(free_ieee80211softmac);static void ieee80211softmac_start_check_rates(struct ieee80211softmac_device *mac){	struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;	/* I took out the sorting check, we're seperating by modulation now. */	if (ri->count)		return;	/* otherwise assume we hav'em all! */	if (mac->ieee->modulation & IEEE80211_CCK_MODULATION) {		ri->rates[ri->count++] = IEEE80211_CCK_RATE_1MB;		ri->rates[ri->count++] = IEEE80211_CCK_RATE_2MB;		ri->rates[ri->count++] = IEEE80211_CCK_RATE_5MB;		ri->rates[ri->count++] = IEEE80211_CCK_RATE_11MB;	}	if (mac->ieee->modulation & IEEE80211_OFDM_MODULATION) {		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_6MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_9MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_12MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_18MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_24MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_36MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_48MB;		ri->rates[ri->count++] = IEEE80211_OFDM_RATE_54MB;	}}int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate){	int search;	u8 search_rate;	for (search = 0; search < ri->count; search++) {		search_rate = ri->rates[search];		search_rate &= ~IEEE80211_BASIC_RATE_MASK;		if (rate == search_rate)			return 1;	}	return 0;}u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,	struct ieee80211softmac_ratesinfo *ri, int basic_only){	u8 user_rate = mac->txrates.user_rate;	int i;	if (ri->count == 0)		return IEEE80211_CCK_RATE_1MB;	for (i = ri->count - 1; i >= 0; i--) {		u8 rate = ri->rates[i];		if (basic_only && !(rate & IEEE80211_BASIC_RATE_MASK))			continue;		rate &= ~IEEE80211_BASIC_RATE_MASK;		if (rate > user_rate)			continue;		if (ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))			return rate;	}	/* If we haven't found a suitable rate by now, just trust the user */	return user_rate;}EXPORT_SYMBOL_GPL(ieee80211softmac_highest_supported_rate);void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,	u8 erp_value){	int use_protection;	int short_preamble;	u32 changes = 0;	/* Barker preamble mode */	short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0			  && mac->associnfo.short_preamble_available) ? 1 : 0;	/* Protection needed? */	use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;	if (mac->bssinfo.short_preamble != short_preamble) {		changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;		mac->bssinfo.short_preamble = short_preamble;	}	if (mac->bssinfo.use_protection != use_protection) {		changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;		mac->bssinfo.use_protection = use_protection;	}	if (mac->bssinfo_change && changes)		mac->bssinfo_change(mac->dev, changes);}void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac){	struct ieee80211softmac_txrates *txrates = &mac->txrates;	u32 change = 0;	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;	txrates->default_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;	txrates->default_fallback = lower_rate(mac, txrates->default_rate);	change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;	txrates->mcast_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);	if (mac->txrates_change)		mac->txrates_change(mac->dev, change);}void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac){	struct ieee80211_device *ieee = mac->ieee;	u32 change = 0;	struct ieee80211softmac_txrates *txrates = &mac->txrates;	struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;	/* TODO: We need some kind of state machine to lower the default rates	 *       if we loose too many packets.	 */	/* Change the default txrate to the highest possible value.	 * The txrate machine will lower it, if it is too high.	 */	if (ieee->modulation & IEEE80211_OFDM_MODULATION)		txrates->user_rate = IEEE80211_OFDM_RATE_24MB;	else		txrates->user_rate = IEEE80211_CCK_RATE_11MB;	txrates->default_rate = IEEE80211_CCK_RATE_1MB;	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;	txrates->default_fallback = IEEE80211_CCK_RATE_1MB;

⌨️ 快捷键说明

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